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:
Later it was edited to include the information about canvas animation and with that new information the correct answer would be using theI know there's a minimum of 1 millisecond in the setInterval method in
javascript. Can I speed this up even more? Like using microseconds?
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);
andif(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
Apt Command Line Interface-Like Yes/No Input
Can't Use '\1' Backreference to Capture-Group in a Function Call in Re.Sub() Repr Expression
Building a Minimal Plugin Architecture in Python
Best Way to Make Django's Login_Required the Default
What's the Best Way to Store a Phone Number in Django Models
Python Sorting by Multiple Criteria
Django: How to Manage Development and Production Settings
Wrapping Long Y Labels in Matplotlib Tight Layout Using Setp
How to Update SQLalchemy Row Entry
Difference Between Exit(0) and Exit(1) in Python
"Permission Denied" Trying to Run Python on Windows 10
Numpy 1.21.2 May Not Yet Support Python 3.10
Should All Python Classes Extend Object
How to Save and Restore Multiple Variables in Python