Improve Current Implementation of a Setinterval

Improve current implementation of a setInterval

To call a function repeatedly with interval seconds between the calls and the ability to cancel future calls:

from threading import Event, Thread

def call_repeatedly(interval, func, *args):
stopped = Event()
def loop():
while not stopped.wait(interval): # the first call is in `interval` secs
func(*args)
Thread(target=loop).start()
return stopped.set

Example:

cancel_future_calls = call_repeatedly(60, print, "Hello, World")
# ...
cancel_future_calls()

Note: this version waits around interval seconds after each call no matter how long func(*args) takes. If metronome-like ticks are desired then the execution could be locked with a timer(): stopped.wait(interval) could be replaced with stopped.wait(interval - timer() % interval) where timer() defines the current time (it may be relative) in seconds e.g., time.time(). See What is the best way to repeatedly execute a function every x seconds in Python?

Speed up setInterval

Update:

Please note that when this answer was written, the question was:

I know there's a minimum of 1 millisecond in the setInterval method in
javascript. Can I speed this up even more? Like using microseconds?

Later it was edited to include the information about canvas animation and with that new information the correct answer would be using the window.requestAnimationFrame method:

function step(timestamp) {
// do something for every frame
window.requestAnimationFrame(step);
}
window.requestAnimationFrame(step);

The step callback gets a DOMHighResTimeStamp timestamp with a precision of 1 microsecond as an argument every time it gets invoked, which is once every time the screen gets refreshed (there's no need to draw anything more frequently because it wouldn't get displayed anyway).

Originally the question was specifically about speeding up the setInterval method, and my original answer was about doing anything in general more frequently than the minimum delay of
setInterval allows (which is 4ms for the nesting levels greater than 5 according to the the WHATWG specification, section 8.4 Timers, or 4ms for the nesting levels of 4 or higher according to this post by James Robinson, and historically it used to work differently).

Original answer:

I don't really know what are you trying to do so I can only speak from experience of what people usually want to do with it.

If you want to call setInterval using microseconds, then the code you want to run has to take considerably less then a millisecond, or otherwise it wouldn't make sense in a single-threaded event loop.

You don't have to worry about blocking the browser for a few milcroseconds so I would suggest using something like this – instead of having:

setInterval(function () {
// YOUR CODE
}, 1/100);

Try doing:

setInterval(function () {
for (var i = 0; i < 1000; i++) {
// YOUR CODE
}
}, 10);

You will actually make your code more efficient by avoiding the callback calling overhead and having longer intervals will make your code run more predictably.

Also no one is going to notice that your code runs in bursts 1000 times every 1/100 of a second, because there's a chance that the browser itself already runs in such bursts thanks to the OS-level process scheduling, and also the screen won't get refreshed faster anyway.

An experiment

Ok, now some experiment. Try this code to see what is actually the shortest interval for your browser:

var start = new Date();
var i = 0, interval = setInterval(function(){
if (++i >= 1000) {
var end = new Date();
alert("The average interval was "
+ ((end-start)/1000)) + " milliseconds";
clearInterval(interval);
}
}, 0);

Note that it won't even be consistent on the same browser. It depends on your system load for example.

Test your browser

Try THIS FIDDLE to test your browser and post your result in the comments if you like. I wonder what will be the record.

Increasing a value with a given interval in Javascript

Yes, you can use setInterval or setTimeout.
So basically the idea is set initial step to 0.

Initiate loop which increases the volume by step number.

Each time button pressed you increase step number:

var step = 0,
count = 0,
res = document.getElementById("count");

var timer = setInterval(loop, 1000);
loop();

function loop() {
count += step;
res.textContent = count;
}

function counter() {
step++;
}
<button type="button" onclick="counter();">Counter</button>
<button type="button" onclick="step=0;count=0">Reset</button>
<span id="count"></span>

Update Javascript Timer Interval periodically

You can use clearInterval based on ids:

let id = setInterval(function () {
// Invoke function every 10 minutes (600000)
loadSyncStatus();
}, 600000);

and

if(response.running_flag=true){
clearInterval(id);
id = setInterval(loadSyncStatus, 60000);
}
else{
clearInterval(id);
id = setInterval(loadSyncStatus, 600000);
}

JavaScript - Is it possible to modify the behaviour of setInterval/setTimeout used by third party scripts (externally hosted)

Well, I'd try to avoid this at all cost (except to try "for fun").

Here may be the result (a setInterval where all intervals >= 100 seconds are replaced by 100 seconds)

// above the use of setInterval by third party code
(function (w, maxVal) {
var f = w.setInterval;
w.setIntervalOld = f;
w.setInterval = function () {
var a = arguments;
if(a.length >= 2 && (a[1] > maxVal)) {
a[1] = maxVal;
}
f.apply(w, a);
};
})(window, 100000);

I tried to make the hack in the most coherent way and window.setIntervalOld is available for your own code. Tell me what it does for you.

How to change the speed of setInterval in real time

Another way would be to just use setTimeout rather than setInterval. Do the check every time so you can keep your speed logic in a seperate function.

var game_over = false;
var score = 0;
function getSpeedFromScore(score)
{
if (score > 20) {
game_over = true;
}

if (score < 10) {
return 1000;
} else {
return 500;
}
}

function spawnEnemyThenWait() {
if (!game_over) {
spawnEnemy();

var speed = getSpeedFromScore(score);
setTimeout(spawnEnemyThenWait, speed);
}
}

JS Fiddle http://jsfiddle.net/bq926xz6/

How can I use setInterval and clearInterval?

setInterval sets up a recurring timer. It returns a handle that you can pass into clearInterval to stop it from firing:

var handle = setInterval(drawAll, 20);

// When you want to cancel it:
clearInterval(handle);
handle = 0; // I just do this so I know I've cleared the interval

On browsers, the handle is guaranteed to be a number that isn't equal to 0; therefore, 0 makes a handy flag value for "no timer set". (Other platforms may return other values; Node.js's timer functions return an object, for instance.)

To schedule a function to only fire once, use setTimeout instead. It won't keep firing. (It also returns a handle you can use to cancel it via clearTimeout before it fires that one time if appropriate.)

setTimeout(drawAll, 20);

Equivalent of setInterval in python

Your solution looks fine to me.

There are several ways to communicate with threads. To order a thread to stop, you can use threading.Event(), which has a wait() method that you can use instead of time.sleep().

stop_event = threading.Event()
...
stop_event.wait(1.)
if stop_event.isSet():
return
...

For your thread to exit when the program is terminated, set its daemon attribute to True before calling start(). This applies to Timer() objects as well because they subclass threading.Thread. See http://docs.python.org/library/threading.html#threading.Thread.daemon

How can I make setInterval also work when a tab is inactive in Chrome?

On most browsers inactive tabs have low priority execution and this can affect JavaScript timers.

If the values of your transition were calculated using real time elapsed between frames instead fixed increments on each interval, you not only workaround this issue but also can achieve a smother animation by using requestAnimationFrame as it can get up to 60fps if the processor isn't very busy.

Here's a vanilla JavaScript example of an animated property transition using requestAnimationFrame:

var target = document.querySelector('div#target')var startedAt, duration = 3000var domain = [-100, window.innerWidth]var range = domain[1] - domain[0]
function start() { startedAt = Date.now() updateTarget(0) requestAnimationFrame(update)}
function update() { let elapsedTime = Date.now() - startedAt
// playback is a value between 0 and 1 // being 0 the start of the animation and 1 its end let playback = elapsedTime / duration
updateTarget(playback) if (playback > 0 && playback < 1) { // Queue the next frame requestAnimationFrame(update) } else { // Wait for a while and restart the animation setTimeout(start, duration/10) }}
function updateTarget(playback) { // Uncomment the line below to reverse the animation // playback = 1 - playback
// Update the target properties based on the playback position let position = domain[0] + (playback * range) target.style.left = position + 'px' target.style.top = position + 'px' target.style.transform = 'scale(' + playback * 3 + ')'}
start()
body {  overflow: hidden;}
div { position: absolute; white-space: nowrap;}
<div id="target">...HERE WE GO</div>


Related Topics



Leave a reply



Submit