The
setTimeout()
and
setInterval()
methods
allow
authors
to
schedule
timer-based
callbacks.
setTimeout
(
handler
[,
timeout
[,
arguments
...
]
]
)
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.
Cancels
the
timeout
set
with
setTimeout()
or
setInterval()
identified
by
handle
.
setInterval
(
handler
[,
timeout
[,
arguments
...
]
]
)
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.
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.
The
setTimeout(
handler
,
timeout
,
...
arguments
)
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.
The
setInterval(
handler
,
timeout
,
...
arguments
)
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.
The
clearTimeout(
handle
)
and
clearInterval(
handle
)
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 .
Assert: base URL is not null, as initiating script is a classic script or a JavaScript module script .
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
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()
).
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.
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.
Optionally, pause while waiting for the user to acknowledge the message.
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.
Pause until the user responds either positively or negatively.
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 .
Pause while waiting for the user's response.
If the user aborts, then return null; otherwise, return the string that the user responded with.
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.
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
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 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
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.