Living
Standard
—
Last
Updated
12
13
June
2024
The
setTimeout()
and
setInterval()
methods
allow
authors
to
schedule
timer-based
callbacks.
id
=
self.
setTimeout
(
handler
[,
timeout
[,
...
arguments
]
])
Support in all current engines.
Schedules a timeout to run handler after timeout milliseconds. Any arguments are passed straight through to the handler .
id
=
self.
setTimeout
(
code
[,
timeout
])
Schedules a timeout to compile and run code after timeout milliseconds.
self.
clearTimeout
(
id
)
Support in all current engines.
Cancels
the
timeout
set
with
setTimeout()
or
setInterval()
identified
by
id
.
id
=
self.
setInterval
(
handler
[,
timeout
[,
...
arguments
]
])
Support in all current engines.
Schedules a timeout to run handler every timeout milliseconds. Any arguments are passed straight through to the handler .
id
=
self.
setInterval
(
code
[,
timeout
])
Schedules a timeout to compile and run code every timeout milliseconds.
self.
clearInterval
(
id
)
Support in all current engines.
Cancels
the
timeout
set
with
setInterval()
or
setTimeout()
identified
by
id
.
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
map
of
active
timers
,
which
is
a
map
,
initially
empty.
Each
key
in
this
map
is
an
identifier
for
a
timer,
and
each
value
is
a
DOMHighResTimeStamp
,
representing
the
expiry
time
for
that
timer.
For
entries
put
in
the
map
of
active
timers
by
the
timer
initialization
steps
,
i.e.,
by
setTimeout()
and
setInterval()
,
the
keys
are
numbers.
For
other
specifications
that
use
the
run
steps
after
a
timeout
algorithm,
the
identifier
is
a
unique
non-numeric
value.
Only
the
numeric-keyed
timers
are
affected
by
clearTimeout()
and
clearInterval()
,
but
all
timers
contribute
to
idle
deadline
computation
,
and
are
cleared
when
the
relevant
global
is
destroyed.
The
setTimeout(
handler
,
timeout
,
...
arguments
)
method
steps
are
to
return
the
result
of
running
the
timer
initialization
steps
given
this
,
handler
,
timeout
,
arguments
,
and
false.
The
setInterval(
handler
,
timeout
,
...
arguments
)
method
steps
are
to
return
the
result
of
running
the
timer
initialization
steps
given
this
,
handler
,
timeout
,
arguments
,
and
true.
The
clearTimeout(
id
)
and
clearInterval(
id
)
method
steps
are
to
remove
this
's
map
of
active
timers
[
id
].
Because
clearTimeout()
and
clearInterval()
clear
entries
from
the
same
map,
either
method
can
be
used
to
clear
timers
created
by
setTimeout()
or
setInterval()
.
The
timer
initialization
steps
,
given
a
WindowOrWorkerGlobalScope
global
,
a
string
or
Function
or
TrustedScript
handler
,
a
number
timeout
,
a
list
arguments
,
a
boolean
repeat
,
and
optionally
(and
only
if
repeat
is
true)
a
number
previousId
,
are:
Let
thisArg
be
global
if
that
is
a
WorkerGlobalScope
object;
otherwise
let
thisArg
be
the
WindowProxy
that
corresponds
to
global
.
If previousId was given, let id be previousId ; otherwise, let id be an implementation-defined integer that is greater than zero and does not already exist in global 's map of active timers .
If the surrounding agent 's event loop 's 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.
Let realm be global 's relevant realm .
Let initiating script be the active script .
Let task be a task that runs the following substeps:
If id does not exist in global 's map of active timers , then abort these steps.
Record timing info for timer handler given handler , global 's relevant settings object , and repeat .
If
handler
is
a
Function
,
then
invoke
handler
given
arguments
with
the
callback
this
value
set
to
thisArg
.
If
this
throws
an
exception,
catch
it,
and
report
the
exception
.
Otherwise:
If previousId was not given:
Let
globalName
be
"
Window
"
if
this
's
relevant
global
object
is
a
Window
object;
"
Worker
"
otherwise.
Let
methodName
be
"
setInterval
"
if
repeat
is
true;
"
setTimeout
"
otherwise.
Let sink be a concatenation of globalName , U+0020 SPACE, and methodName .
Set
handler
to
the
result
of
invoking
the
Get
Trusted
Type
compliant
string
algorithm
with
TrustedScript
,
this
's
relevant
global
object
,
handler
,
sink
,
and
"
script
".
Assert : handler is a string.
Perform
HostEnsureCanCompileStrings
EnsureCSPDoesNotBlockStringCompilation
(
realm
,
«
»,
handler
,
handler
,
timer,
«
»,
handler
).
If
this
throws
an
exception,
catch
it,
report
the
exception
,
and
abort
these
steps.
Let settings object be global 's relevant settings object .
Let fetch options be the default classic script fetch options .
Let base URL be settings object 's API base URL .
If initiating script is not null, then:
Set
fetch
options
to
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
,
referrer
policy
is
initiating
script
's
fetch
options
's
referrer
policy
,
and
fetch
priority
is
"
auto
".
Set base URL to initiating script 's base URL .
The
effect
of
these
steps
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 handler , settings object , base URL , and fetch options .
Run the classic script script .
If id does not exist in global 's map of active timers , then abort these steps.
It
might
have
been
removed
via
the
author
code
in
handler
calling
clearTimeout()
or
clearInterval()
.
If repeat is true, then perform the timer initialization steps again, given global , handler , timeout , arguments , true, and id .
Otherwise, remove global 's map of active timers [ id ].
Increment nesting level by one.
Set task 's timer nesting level to nesting level .
Let completionStep be an algorithm step which queues a global task on the timer task source given global to run task .
Run
steps
after
a
timeout
given
global
,
"
setTimeout/setInterval
",
timeout
,
completionStep
,
and
id
.
Return id .
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);
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 id = setTimeout(rescheduleWork, 0); // preschedule next iteration
if (doExpensiveWork())
clearTimeout(id); // clear the timeout if we don't need it
}
function scheduleWork() {
setTimeout(rescheduleWork, 0);
}
scheduleWork();
//
queues
a
task
to
do
lots
of
work
To
run
steps
after
a
timeout
,
given
a
WindowOrWorkerGlobalScope
global
,
a
string
orderingIdentifier
,
a
number
milliseconds
,
a
set
of
steps
completionSteps
,
and
an
optional
value
timerKey
:
Assert : if timerKey is given, then the caller of this algorithm is the timer initialization steps . (Other specifications must not pass timerKey .)
If timerKey is not given, then set it to a new unique non-numeric value.
Let startTime be the current high resolution time given global .
Set global 's map of active timers [ timerKey ] to startTime plus milliseconds .
Run the following steps in parallel :
If
global
is
a
Window
object,
wait
until
global
's
associated
Document
has
been
fully
active
for
a
further
milliseconds
milliseconds
(not
necessarily
consecutively).
Otherwise,
global
is
a
WorkerGlobalScope
object;
wait
until
milliseconds
milliseconds
have
passed
with
the
worker
not
suspended
(not
necessarily
consecutively).
Wait until any invocations of this algorithm that had the same global and orderingIdentifier , that started before this one, and whose milliseconds is less than or equal to this one's, have completed.
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.
Perform completionSteps .
If timerKey is a non-numeric value, remove global 's map of active timers [ timerKey ].
Run
steps
after
a
timeout
is
meant
to
be
used
by
other
specifications
that
want
to
execute
developer-supplied
code
after
a
developer-supplied
timeout,
in
a
similar
manner
to
setTimeout()
.
(Note,
however,
it
does
not
have
the
nesting
and
clamping
behavior
of
setTimeout()
.)
Such
specifications
can
choose
an
orderingIdentifier
to
ensure
ordering
within
their
specification's
timeouts,
while
not
constraining
ordering
with
respect
to
other
specification's
timeouts.
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
once
the
JavaScript
execution
context
stack
is
next
empty,
which
happens
once
all
currently
executing
synchronous
JavaScript
has
run
to
completion.
This
doesn't
yield
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.
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
currently
executing
synchronous
JavaScript
has
run
to
completion.
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 JavaScript execution context stack empties, 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
currently
executing
synchronous
JavaScript
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()
).
window
.
alert
(
message
)
Support in all current engines.
Displays a modal alert with the given message, and waits for the user to dismiss it.
result
=
window
.
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.
result
=
window
.
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.
The
alert()
and
alert(
message
)
method
steps
are:
If we cannot show simple dialogs for this , then return.
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.
Invoke
WebDriver
BiDi
user
prompt
opened
with
this
,
"
alert
",
and
message
.
Optionally, pause while waiting for the user to acknowledge the message.
Invoke WebDriver BiDi user prompt closed with this and true.
This
method
is
defined
using
two
overloads,
instead
of
using
an
optional
argument,
for
historical
reasons.
The
practical
impact
of
this
is
that
alert(undefined)
is
treated
as
alert("undefined")
,
but
alert()
is
treated
as
alert("")
.
The
confirm(
message
)
method
steps
are:
If we cannot show simple dialogs for this , then return false.
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.
Invoke
WebDriver
BiDi
user
prompt
opened
with
this
,
"
confirm
",
and
message
.
Pause until the user responds either positively or negatively.
Invoke WebDriver BiDi user prompt closed with this , and true if the user responded positively or false otherwise.
If the user responded positively, return true; otherwise, the user responded negatively: return false.
The
prompt(
message
,
default
)
method
steps
are:
If we cannot show simple dialogs for this , then return null.
Set message to the result of normalizing newlines given message .
Set message to the result of optionally truncating 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 .
Invoke
WebDriver
BiDi
user
prompt
opened
with
this
,
"
prompt
",
message
,
and
default
.
Pause while waiting for the user's response.
Let result be null if the user aborts, or otherwise the string that the user responded with.
Invoke WebDriver BiDi user prompt closed with this , false if result is null or true otherwise, and result .
Return result .
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.
We
cannot
show
simple
dialogs
for
a
Window
window
when
the
following
algorithm
returns
true:
If
the
active
sandboxing
flag
set
of
window
's
associated
Document
has
the
sandboxed
modals
flag
set,
then
return
true.
If window 's relevant settings object 's origin and window 's relevant settings object 's top-level origin are not same origin-domain , then return true.
Optionally, return true. (For example, the user agent might give the user the option to ignore all modal dialogs, and would thus abort at this step whenever the method was invoked.)
Return false.
Support in all current engines.
window
.
print
()
Prompts the user to print the page.
The
print()
method
steps
are:
Let
document
be
this
's
associated
Document
.
If document is not fully active , then return.
If document 's unload counter is greater than 0, then return.
If document is ready for post-load tasks , then run the printing steps for document .
Otherwise, set document 's print when loaded flag.
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
for
a
Document
document
are:
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 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
document
,
as
well
as
any
child
navigable
in
it.
Firing in children only doesn't seem right here, and some tasks likely need to be queued. See issue #5096 .
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 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
document
,
as
well
as
any
child
navigables
in
it.
Firing in children only doesn't seem right here, and some tasks likely need to be queued. See issue #5096 .
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.