The setTimeout()
and setInterval()
methods allow authors to schedule timer-based
callbacks.
setTimeout
( handler [, timeout [, arguments... ] ] )WindowOrWorkerGlobalScope/setTimeout
Support in all current engines.
WindowOrWorkerGlobalScope/setTimeout
Support in all current engines.
Schedules a timeout to run handler after timeout milliseconds. Any arguments are passed straight through to the handler.
setTimeout
( code [, timeout ] )Schedules a timeout to compile and run code after timeout milliseconds.
clearTimeout
( handle )WindowOrWorkerGlobalScope/clearTimeout
Support in all current engines.
WindowOrWorkerGlobalScope/clearTimeout
Support in all current engines.
Cancels the timeout set with setTimeout()
or setInterval()
identified by handle.
setInterval
( handler [, timeout [, arguments... ] ] )WindowOrWorkerGlobalScope/setInterval
Support in all current engines.
WindowOrWorkerGlobalScope/setInterval
Support in all current engines.
Schedules a timeout to run handler every timeout milliseconds. Any arguments are passed straight through to the handler.
setInterval
( code [, timeout ] )Schedules a timeout to compile and run code every timeout milliseconds.
clearInterval
( handle )WindowOrWorkerGlobalScope/clearInterval
Support in all current engines.
WindowOrWorkerGlobalScope/clearInterval
Support in all current engines.
Cancels the timeout set with setInterval()
or setTimeout()
identified by handle.
Timers can be nested; after five such nested timers, however, the interval is forced to be at least four milliseconds.
This API does not guarantee that timers will run exactly on schedule. Delays due to CPU load, other tasks, etc, are to be expected.
To run tasks of several milliseconds back to back without any delay, while still yielding back to the browser to avoid starving the user interface (and to avoid the browser killing the script for hogging the CPU), simply queue the next timer before performing work:
function doExpensiveWork() {
var done = false ;
// ...
// this part of the function takes up to five milliseconds
// set done to true if we're done
// ...
return done;
}
function rescheduleWork() {
var handle = setTimeout( rescheduleWork, 0 ); // preschedule next iteration
if ( doExpensiveWork())
clearTimeout( handle); // clear the timeout if we don't need it
}
function scheduleWork() {
setTimeout( rescheduleWork, 0 );
}
scheduleWork(); // queues a task to do lots of work
WindowOrWorkerGlobalScope/queueMicrotask
Support in all current engines.
queueMicrotask
(callback)Queues a microtask to run the given callback.
The queueMicrotask()
method allows authors to schedule
a callback on the microtask queue. This allows their code to run after the
currently-executing task has run to completion and the
JavaScript execution context stack is empty, but without yielding control back to the
event loop, as would be the case when using, for example, setTimeout(f, 0)
.
Authors ought to be aware that scheduling a lot of microtasks has the same performance
downsides as running a lot of synchronous code. Both will prevent the browser from doing its own
work, such as rendering or scrolling. In many cases, requestAnimationFrame()
or
requestIdleCallback()
is a better choice. In particular, if the goal is to run code
before the next rendering cycle, that is the purpose of requestAnimationFrame()
.
As can be seen from the following examples, the best way of thinking about queueMicrotask()
is as a mechanism for rearranging synchronous
code, effectively placing the queued code immediately after the current task's worth of non-queued
JavaScript.
The most common reason for using queueMicrotask()
is
to create consistent ordering, even in the cases where information is available synchronously,
without introducing undue delay.
For example, consider a custom element firing a load
event, that also
maintains an internal cache of previously-loaded data. A naïve implementation might look
like:
MyElement. prototype. loadData = function ( url) {
if ( this . _cache[ url]) {
this . _setData( this . _cache[ url]);
this . dispatchEvent( new Event( "load" ));
} else {
fetch( url). then( res => res. arrayBuffer()). then( data => {
this . _cache[ url] = data;
this . _setData( data);
this . dispatchEvent( new Event( "load" ));
});
}
};
This naïve implementation is problematic, however, in that it causes its users to experience inconsistent behavior. For example, code such as
element. addEventListener( "load" , () => console. log( "loaded" ));
console. log( "1" );
element. loadData();
console. log( "2" );
will sometimes log "1, 2, loaded" (if the data needs to be fetched), and sometimes log "1,
loaded, 2" (if the data is already cached). Similarly, after the call to loadData()
, it will be inconsistent whether or not the data is set on the
element.
To get a consistent ordering, queueMicrotask()
can be
used:
MyElement. prototype. loadData = function ( url) {
if ( this . _cache[ url]) {
queueMicrotask(() => {
this . _setData( this . _cache[ url]);
this . dispatchEvent( new Event( "load" ));
});
} else {
fetch( url). then( res => res. arrayBuffer()). then( data => {
this . _cache[ url] = data;
this . _setData( data);
this . dispatchEvent( new Event( "load" ));
});
}
};
By essentially rearranging the queued code to be after the currently-executing task, this ensures a consistent ordering and update of the element's state.
Another interesting use of queueMicrotask()
is to
allow uncoordinated "batching" of work by multiple callers. For example, consider a library
function that wants to send data somewhere as soon as possible, but doesn't want to make multiple
network requests if doing so is easily avoidable. One way to balance this would be like so:
const queuedToSend = [];
function sendData( data) {
queuedToSend. push( data);
if ( queuedToSend. length === 1 ) {
queueMicrotask(() => {
const stringToSend = JSON. stringify( queuedToSend);
queuedToSend. length = 0 ;
fetch( "/endpoint" , stringToSend);
});
}
}
With this architecture, multiple subsequent calls to sendData()
within
the same turn of the event loop will be batched together into one fetch()
call, but
with no intervening event loop tasks preempting the fetch (as would have happened with similar
code that instead used setTimeout()
).
alert
(message)Support in all current engines.
Displays a modal alert with the given message, and waits for the user to dismiss it.
confirm
(message)Support in all current engines.
Displays a modal OK/Cancel prompt with the given message, waits for the user to dismiss it, and returns true if the user clicks OK and false if the user clicks Cancel.
prompt
(message [, default] )Support in all current engines.
Displays a modal text control prompt with the given message, waits for the user to dismiss it, and returns the value that the user entered. If the user cancels the prompt, then returns null instead. If the second argument is present, then the given value is used as a default.
Logic that depends on tasks or microtasks, such as media elements loading their media data, are stalled when these methods are invoked.
Support in all current engines.
print
()Prompts the user to print the page.