The
setTimeout()
and
setInterval()
methods
allow
authors
to
schedule
timer-based
callbacks.
handle
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 .
handle
id
=
self.
setTimeout
(
code
[,
timeout
])
Schedules a timeout to compile and run code after timeout milliseconds.
self.
clearTimeout
(
handle
id
)
Support in all current engines.
Cancels
the
timeout
set
with
setTimeout()
or
setInterval()
identified
by
handle
id
.
handle
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 .
handle
id
=
self.
setInterval
(
code
[,
timeout
])
Schedules a timeout to compile and run code every timeout milliseconds.
self.
clearInterval
(
handle
id
)
Support in all current engines.
Cancels
the
timeout
set
with
setInterval()
or
setTimeout()
identified
by
handle
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
identified
by
a
number,
which
must
be
unique
within
the
list
for
the
lifetime
of
the
object
that
implements
the
WindowOrWorkerGlobalScope
mixin,
and
each
value
is
a
DOMHighResTimeStamp
,
representing
the
expiry
time
for
that
timer.
The
setTimeout(
handler
,
timeout
,
...
arguments
)
method
must
steps
are
to
return
the
value
returned
by
result
of
running
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
given
this
,
method
context
handler
,
and
the
repeat
flag
set
to
timeout
,
arguments
,
and
false.
The
setInterval(
handler
,
timeout
,
...
arguments
)
method
must
steps
are
to
return
the
value
returned
by
result
of
running
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
given
this
,
method
context
handler
,
and
the
repeat
flag
set
to
timeout
,
arguments
,
and
true.
The
clearTimeout(
and
handle
id
)
clearInterval(
handle
id
)
methods
must
method
steps
are
to
remove
this
's
map
of
active
timers
[
handle
]
of
the
WindowOrWorkerGlobalScope
object
on
which
the
method
was
invoked,
if
any,
where
handle
id
is
the
argument
passed
to
the
method.
].
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
,
which
are
invoked
with
some
method
arguments,
given
a
WindowOrWorkerGlobalScope
method
context
global
,
a
string
or
Function
handler
,
a
number
timeout
,
a
list
arguments
,
a
boolean
repeat
flag
which
can
be
true
or
false,
,
and
optionally
(and
only
if
the
repeat
flag
is
true)
a
number
previous
handle
previousId
,
are
as
follows:
are:
Let
method
context
proxy
thisArg
be
method
context
global
if
that
is
a
WorkerGlobalScope
object,
or
else
object;
otherwise
let
thisArg
be
the
WindowProxy
that
corresponds
to
method
context
global
.
If
previous
handle
previousId
was
provided,
given,
let
handle
id
be
previous
handle
previousId
;
otherwise,
let
handle
id
be
an
implementation-defined
integer
that
is
greater
than
zero
that
will
identify
the
timeout
to
be
set
by
this
call
in
the
list
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
callerRealm
be
the
current
Realm
Record
,
and
calleeRealm
be
method
context
global
's
JavaScript
realm
relevant
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
handle
id
does
not
exist
in
method
context
global
's
map
of
active
timers
,
then
abort
these
steps.
If
the
first
method
argument
handler
is
a
Function
Invoke
the
Function
,
then
invoke
.
Use
the
third
and
subsequent
method
arguments
(if
any)
as
the
arguments
for
invoking
the
Function
.
Use
method
context
proxy
handler
as
given
arguments
with
the
callback
this
value
.
set
to
thisArg
.
If
this
throws
an
exception,
catch
it,
and
report
the
exception
.
Otherwise
Otherwise:
Assert: handler is a string.
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
global
's
environment
relevant
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
handler
,
settings
object
,
base
URL
,
and
fetch
options
.
Run the classic script script .
If
the
repeat
flag
is
true,
then
call
perform
the
timer
initialization
steps
again,
passing
them
the
same
method
arguments,
the
same
given
method
context
global
,
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,
arguments
,
true,
and
timeout
is
less
than
4,
then
set
timeout
to
4.
id
.
Increment nesting level by one.
Let
Set
task
's
timer
nesting
level
be
to
nesting
level
.
Let startTime be the current high resolution time .
Set
global
's
map
of
active
timers
[
handle
id
]
to
startTime
plus
timeout
.
Return
handle
,
and
then
continue
running
this
algorithm
Run
the
following
steps
in
parallel
.
:
If
method
context
global
is
a
Window
object,
wait
until
the
Document
associated
with
method
context
global
's
associated
Document
has
been
fully
active
for
a
further
timeout
milliseconds
(not
necessarily
consecutively).
Otherwise,
method
context
global
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
global
,
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
global
to
run
task
.
Once
the
task
has
been
processed,
if
the
repeat
flag
is
false,
it
is
safe
to
remove
the
entry
for
handle
id
from
the
list
map
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).
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 handle = setTimeout(rescheduleWork, 0); // preschedule next iteration
var id = setTimeout(rescheduleWork, 0); // preschedule next iteration
if (doExpensiveWork())
clearTimeout(handle); // clear the timeout if we don't need it
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
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.
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.
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
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.