The setTimeout()
and setInterval()
methods allow authors to schedule timer-based
callbacks.
setTimeout
( handler [, timeout [, arguments... ] ] )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 )Cancels the timeout set with setTimeout()
or setInterval()
identified by handle.
setInterval
( handler [, timeout [, arguments... ] ] )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 )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.
Objects that implement the WindowOrWorkerGlobalScope
mixin have a list of active timers. Each entry in this lists is identified by a number, which must
be unique within the list for the lifetime of the object that implements the
WindowOrWorkerGlobalScope
mixin.
WindowOrWorkerGlobalScope/setTimeout
Support in all current engines.
WindowOrWorkerGlobalScope/setTimeout
Support in all current engines.
The setTimeout()
method must return the value returned
by the timer initialization steps, passing them the method's arguments, the object on
which the method for which the algorithm is running is implemented (a Window
or
WorkerGlobalScope
object) as the method context, and the repeat
flag set to false.
WindowOrWorkerGlobalScope/setInterval
Support in all current engines.
WindowOrWorkerGlobalScope/setInterval
Support in all current engines.
The setInterval()
method must return the value returned
by the timer initialization steps, passing them the method's arguments, the object on
which the method for which the algorithm is running is implemented (a Window
or
WorkerGlobalScope
object) as the method context, and the repeat
flag set to true.
WindowOrWorkerGlobalScope/clearTimeout
Support in all current engines.
WindowOrWorkerGlobalScope/clearTimeout
Support in all current engines.
WindowOrWorkerGlobalScope/clearInterval
Support in all current engines.
WindowOrWorkerGlobalScope/clearInterval
Support in all current engines.
The clearTimeout()
and clearInterval()
methods must clear the entry identified as handle from the list of active
timers of the WindowOrWorkerGlobalScope
object on which the method was
invoked, if any, where handle is the argument passed to the method. (If
handle does not identify an entry in the list of active timers of the
WindowOrWorkerGlobalScope
object on which the method was invoked, the method does
nothing.)
Because clearTimeout()
and clearInterval()
clear entries from the same list, either method
can be used to clear timers created by setTimeout()
or setInterval()
.
The timer initialization steps, which are invoked with some method arguments, a method context, a repeat flag which can be true or false, and optionally (and only if the repeat flag is true) a previous handle, are as follows:
Let method context proxy be method context if that
is a WorkerGlobalScope
object, or else the WindowProxy
that corresponds
to method context.
If previous handle was provided, let handle be previous handle; otherwise, let handle be an implementation-defined integer that is greater than zero that will identify the timeout to be set by this call in the list of active timers.
If previous handle was not provided, add an entry to the list of active timers for handle.
Let callerRealm be the current Realm Record, and calleeRealm be method context's JavaScript realm.
Let initiating script be the active script.
Assert: initiating script is not null, since this algorithm is always called from some script.
Let task be a task that runs the following substeps:
If the entry for handle in the list of active timers has been cleared, then abort these steps.
Run the appropriate set of steps from the following list:
Function
Invoke the Function
. Use the third and subsequent method arguments (if any)
as the arguments for invoking the Function
. Use
method context proxy as the callback this
value. If this throws an exception, catch it, and report the
exception.
Perform HostEnsureCanCompileStrings(callerRealm, calleeRealm). If this throws an exception, catch it, report the exception, and abort these steps.
Let script source be the first method argument.
Let settings object be method context's environment settings object.
Let base URL be initiating script's base URL.
Let fetch options be a script fetch options whose cryptographic nonce is initiating
script's fetch options's
cryptographic nonce, integrity metadata is the empty
string, parser metadata is
"not-parser-inserted
", credentials mode is
initiating script's fetch
options's credentials
mode, and referrer
policy is initiating script's fetch options's referrer policy.
The effect of these options ensures that the string compilation done by
setTimeout()
and setInterval()
behaves equivalently to that done by
eval()
. That is, module script fetches via import()
will behave the same in both contexts.
Let script be the result of creating a classic script given script source, settings object, base URL, and fetch options.
Run the classic script script.
If the repeat flag is true, then call timer initialization steps again, passing them the same method arguments, the same method context, with the repeat flag still set to true, and with the previous handle set to handler.
Let timeout be the second method argument.
If the currently running task is a task that was created by this algorithm, then let nesting level be the task's timer nesting level. Otherwise, let nesting level be zero.
The task's timer nesting level is used both for nested calls to
setTimeout()
, and for the repeating timers created by setInterval()
. (Or, indeed, for any combination of the two.) In
other words, it represents nested invocations of this algorithm, not of a particular method.
If timeout is less than 0, then set timeout to 0.
If nesting level is greater than 5, and timeout is less than 4, then set timeout to 4.
Increment nesting level by one.
Let task's timer nesting level be nesting level.
Return handle, and then continue running this algorithm in parallel.
If method context is a Window
object, wait until the
Document
associated with method context has been fully
active for a further timeout milliseconds (not necessarily
consecutively).
Otherwise, method context is a WorkerGlobalScope
object;
wait until timeout milliseconds have passed with the worker not suspended
(not necessarily consecutively).
Wait until any invocations of this algorithm that had the same method context, that started before this one, and whose timeout is equal to or less than this one's, have completed.
Argument conversion as defined by Web IDL (for example, invoking toString()
methods on objects passed as the first argument) happens in the
algorithms defined in Web IDL, before this algorithm is invoked.
So for example, the following rather silly code will result in the log containing "ONE TWO
":
var log = '';
function logger(s) { log += s + ' '; }
setTimeout({ toString: function () {
setTimeout("logger('ONE')", 100);
return "logger('TWO')";
} }, 100);
Optionally, wait a further implementation-defined length of time.
This is intended to allow user agents to pad timeouts as needed to optimize the power usage of the device. For example, some processors have a low-power mode where the granularity of timers is reduced; on such platforms, user agents can slow timers down to fit this schedule instead of requiring the processor to use the more accurate mode with its associated higher power usage.
Queue a global task on the timer task source given method context to run task.
Once the task has been processed, if the repeat flag is false, it is safe to remove the entry for handle from the list of active timers (there is no way for the entry's existence to be detected past this point, so it does not technically matter one way or the other).
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.
The queueMicrotask(callback)
method must
queue a microtask to invoke
callback, and if callback throws an exception, report the
exception.
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)Displays a modal alert with the given message, and waits for the user to dismiss it.
confirm
(message)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] )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.
To optionally truncate a simple dialog string s, return either s itself or some string derived from s that is shorter. User agents should not provide UI for displaying the elided portion of s, as this makes it too easy for abusers to create dialogs of the form "Important security alert! Click 'Show More' for full details!".
For example, a user agent might want to only display the first 100 characters of a message. Or, a user agent might replace the middle of the string with "…". These types of modifications can be useful in limiting the abuse potential of unnaturally large, trustworthy-looking system dialogs.
Support in all current engines.
The alert(message)
method, when invoked, must run the following steps:
If the event loop's termination nesting level is nonzero, optionally return.
If the active sandboxing flag set of this Window
object's associated Document
has the sandboxed
modals flag set, then return.
Optionally, return. (For example, the user agent might give the user the option to ignore all alerts, and would thus abort at this step whenever the method was invoked.)
If the method was invoked with no arguments, then let message be the empty string; otherwise, let message be the method's first argument.
Set message to the result of normalizing newlines given message.
Set message to the result of optionally truncating message.
Show message to the user, treating U+000A LF as a line break.
Optionally, pause while waiting for the user to acknowledge the message.
Support in all current engines.
The confirm(message)
method, when invoked, must run the
following steps:
If the event loop's termination nesting level is nonzero, optionally return false.
If the active sandboxing flag set of this Window
object's associated Document
has the sandboxed
modals flag set, then return.
Optionally, return false. (For example, the user agent might give the user the option to ignore all prompts, and would thus abort at this step whenever the method was invoked.)
Set message to the result of normalizing newlines given message.
Set message to the result of optionally truncating message.
Show message to the user, treating U+000A LF as a line break, and ask the user to respond with a positive or negative response.
Pause until the user responds either positively or negatively.
If the user responded positively, return true; otherwise, the user responded negatively: return false.
Support in all current engines.
The prompt(message,
default)
method, when invoked, must run the following steps:
If the event loop's termination nesting level is nonzero, optionally return null.
If the active sandboxing flag set of this Window
object's associated Document
has the sandboxed
modals flag set, then return.
Optionally, return null. (For example, the user agent might give the user the option to ignore all prompts, and would thus abort at this step whenever the method was invoked.)
Set message to the result of optionally truncating message.
Set message to the result of normalizing newlines given message.
Set default to the result of optionally truncating default.
Show message to the user, treating U+000A LF as a line break, and ask the user to either respond with a string value or abort. The response must be defaulted to the value given by default.
Pause while waiting for the user's response.
If the user aborts, then return null; otherwise, return the string that the user responded with.
Support in all current engines.
print
()Prompts the user to print the page.
When the print()
method is
invoked, if the Document
is ready for post-load tasks, then the user
agent must run the printing steps. Otherwise, the user agent must only set the
print when loaded flag on the Document
.
User agents should also run the printing steps whenever the user asks for the opportunity to obtain a physical form (e.g. printed copy), or the representation of a physical form (e.g. PDF copy), of a document.
The printing steps are as follows:
The user agent may display a message to the user or return (or both).
For instance, a kiosk browser could silently ignore any invocations of the
print()
method.
For instance, a browser on a mobile device could detect that there are no printers in the vicinity and display a message saying so before continuing to offer a "save to PDF" option.
If the active sandboxing flag set of this Window
object's associated Document
has the sandboxed
modals flag set, then return.
If the printing dialog is blocked by a Document
's sandbox,
then neither the beforeprint
nor afterprint
events will be fired.
The user agent must fire an event named beforeprint
at the relevant global object of the
Document
that is being printed, as well as any child browsing contexts in it.
The beforeprint
event can be used to
annotate the printed copy, for instance adding the time at which the document was printed.
The user agent should offer the user the opportunity to obtain a physical form (or the representation of a physical form) of the document. The user agent may wait for the user to either accept or decline before returning; if so, the user agent must pause while the method is waiting. Even if the user agent doesn't wait at this point, the user agent must use the state of the relevant documents as they are at this point in the algorithm if and when it eventually creates the alternate form.
The user agent must fire an event named afterprint
at the relevant global object of the
Document
that is being printed, as well as any child browsing contexts in it.
The afterprint
event can be used to
revert annotations added in the earlier event, as well as showing post-printing UI. For
instance, if a page is walking the user through the steps of applying for a home loan, the
script could automatically advance to the next step after having printed a form or other.