Movatterモバイル変換


[0]ホーム

URL:


MDN Web Docs

Window: setTimeout() method

BaselineWidely available *

ThesetTimeout() method of theWindow interface sets a timer which executes a function or specified piece of code once the timer expires.

Syntax

js
setTimeout(code)setTimeout(code, delay)setTimeout(functionRef)setTimeout(functionRef, delay)setTimeout(functionRef, delay, param1)setTimeout(functionRef, delay, param1, param2)setTimeout(functionRef, delay, param1, param2, /* …, */ paramN)

Parameters

functionRef

Afunction to be executed after the timer expires.

code

An alternative syntax that allows you to include a string instead of a function,which is compiled and executed when the timer expires. This syntax isnotrecommended for the same reasons that make usingeval() a security risk.

delayOptional

The time, in milliseconds that the timer should wait beforethe specified function or code is executed. If this parameter is omitted, a value of 0is used, meaning execute "immediately", or more accurately, the next event cycle.

Note that in either case, the actual delay may be longer than intended; seeReasons for delays longer than specified below.

Also note that if the value isn't a number, implicittype coercion is silently done on the value to convert it to a number — which can lead to unexpected and surprising results; seeNon-number delay values are silently coerced into numbers for an example.

param1, …,paramNOptional

Additional arguments which are passed through to the function specified byfunctionRef.

Return value

ThesetTimeout() method returns a positive integer (typically within the range of 1 to 2,147,483,647) that uniquely identifies the timer created by the call. This identifier, often referred to as a "timeout ID", can be passed toclearTimeout() to cancel the timer.

Within the same global environment (e.g., a specific window or worker) the timeout ID is guaranteed not to be reused for any new timer as long as the original timer remains active. However, separate global environments maintain their own independent pools of timer IDs.

Description

Timeouts are cancelled usingWindow.clearTimeout().

To call a function repeatedly (e.g., everyN milliseconds), consider usingsetInterval().

Non-number delay values are silently coerced into numbers

IfsetTimeout() is called withdelay value that's not a number, implicittype coercion is silently done on the value to convert it to a number. For example, the following code incorrectly uses the string"1000" for thedelay value, rather than the number1000 – but it nevertheless works, because when the code runs, the string is coerced into the number1000, and so the code executes 1 second later.

js
setTimeout(() => {  console.log("Delayed for 1 second.");}, "1000");

But in many cases, the implicit type coercion can lead to unexpected and surprising results. For example, when the following code runs, the string"1 second" ultimately gets coerced into the number0 — and so, the code executes immediately, with zero delay.

js
setTimeout(() => {  console.log("Delayed for 1 second.");}, "1 second");

Therefore, don't use strings for thedelay value but instead always use numbers:

js
setTimeout(() => {  console.log("Delayed for 1 second.");}, 1000);

Working with asynchronous functions

setTimeout() is an asynchronous function, meaning that the timer function will not pause execution of other functions in the functions stack.In other words, you cannot usesetTimeout() to create a "pause" before the next function in the function stack fires.

See the following example:

js
setTimeout(() => {  console.log("this is the first message");}, 5000);setTimeout(() => {  console.log("this is the second message");}, 3000);setTimeout(() => {  console.log("this is the third message");}, 1000);// Output:// this is the third message// this is the second message// this is the first message

Notice that the first function does not create a 5-second "pause" before calling the second function. Instead, the first function is called, but waits 5 seconds toexecute. While the first function is waiting to execute, the second function is called, and a 3-second wait is applied to the second function before it executes. Since neitherthe first nor the second function's timers have completed, the third function is called and completes its execution first. Then the second follows. Then finally the first functionis executed after its timer finally completes.

To create a progression in which one function only fires after the completion of another function, see the documentation onPromises.

The "this" problem

When you pass a method tosetTimeout(), it will be invoked with athis value that may differ from yourexpectation. The general issue is explained in detail in theJavaScript reference.

Code executed bysetTimeout() is called from an execution context separatefrom the function from whichsetTimeout was called. The usual rules forsetting thethis keyword for the called function apply, and if you have notsetthis in the call or withbind, it will default tothewindow (orglobal) object, even instrict mode. It will not be the same as thethis value for the function that calledsetTimeout.

See the following example:

js
const myArray = ["zero", "one", "two"];myArray.myMethod = function (sProperty) {  console.log(arguments.length > 0 ? this[sProperty] : this);};myArray.myMethod(); // prints "zero,one,two"myArray.myMethod(1); // prints "one"

The above works because whenmyMethod is called, itsthis isset tomyArray by the call, so within the function,this[sProperty] is equivalent tomyArray[sProperty]. However,in the following:

js
setTimeout(myArray.myMethod, 1.0 * 1000); // prints "[object Window]" after 1 secondsetTimeout(myArray.myMethod, 1.5 * 1000, "1"); // prints "undefined" after 1.5 seconds

ThemyArray.myMethod function is passed tosetTimeout, thenwhen it's called, itsthis is not set, so it defaults to thewindow object.

There's also no option to pass athisArg tosetTimeout as there is in Array methods such asforEach() andreduce(). As shown below,usingcall to setthis doesn't work either.

js
setTimeout.call(myArray, myArray.myMethod, 2.0 * 1000); // errorsetTimeout.call(myArray, myArray.myMethod, 2.5 * 1000, 2); // same error

Solutions

Use a wrapper function

A common way to solve the problem is to use a wrapper function that setsthis to the required value:

js
setTimeout(function () {  myArray.myMethod();}, 2.0 * 1000); // prints "zero,one,two" after 2 secondssetTimeout(function () {  myArray.myMethod("1");}, 2.5 * 1000); // prints "one" after 2.5 seconds

The wrapper function can be an arrow function:

js
setTimeout(() => {  myArray.myMethod();}, 2.0 * 1000); // prints "zero,one,two" after 2 secondssetTimeout(() => {  myArray.myMethod("1");}, 2.5 * 1000); // prints "one" after 2.5 seconds
Use bind()

Alternatively, you can usebind() to set the value ofthis for all calls to a given function:

js
const myArray = ["zero", "one", "two"];const myBoundMethod = function (sProperty) {  console.log(arguments.length > 0 ? this[sProperty] : this);}.bind(myArray);myBoundMethod(); // prints "zero,one,two" because 'this' is bound to myArray in the functionmyBoundMethod(1); // prints "one"setTimeout(myBoundMethod, 1.0 * 1000); // still prints "zero,one,two" after 1 second because of the bindingsetTimeout(myBoundMethod, 1.5 * 1000, "1"); // prints "one" after 1.5 seconds

Passing string literals

Passing a string instead of a function tosetTimeout() has the same problems as usingeval().

js
// Don't do thissetTimeout("console.log('Hello World!');", 500);
js
// Do this insteadsetTimeout(() => {  console.log("Hello World!");}, 500);

A string passed tosetTimeout() is evaluated in the global context, so local symbols in the context wheresetTimeout() was called will not be available when the string is evaluated as code.

Reasons for delays longer than specified

There are a number of reasons why a timeout may take longer to fire than anticipated.This section describes the most common reasons.

Nested timeouts

As specified in theHTML standard,browsers will enforce a minimum timeout of 4 milliseconds once a nested call tosetTimeout has been scheduled 5 times.

This can be seen in the following example, in which we nest a call tosetTimeout with a delay of0 milliseconds,and log the delay each time the handler is called. The first four times, the delay is approximately 0 milliseconds, and after that it isapproximately 4 milliseconds:

html
<button>Run</button><table>  <thead>    <tr>      <th>Previous</th>      <th>This</th>      <th>Actual delay</th>    </tr>  </thead>  <tbody></tbody></table>
js
let last = 0;let iterations = 10;function timeout() {  // log the time of this call  log(new Date().getMilliseconds());  // if we are not finished, schedule the next call  if (iterations-- > 0) {    setTimeout(timeout, 0);  }}function run() {  // clear the log  const log = document.querySelector("#log");  while (log.lastElementChild) {    log.removeChild(log.lastElementChild);  }  // initialize iteration count and the starting timestamp  iterations = 10;  last = new Date().getMilliseconds();  // start timer  setTimeout(timeout, 0);}function log(now) {  // log the last timestamp, the new timestamp, and the difference  const tableBody = document.getElementById("log");  const logRow = tableBody.insertRow();  logRow.insertCell().textContent = last;  logRow.insertCell().textContent = now;  logRow.insertCell().textContent = now - last;  last = now;}document.querySelector("#run").addEventListener("click", run);
* {  font-family: monospace;}th,td {  padding: 0 10px 0 10px;  text-align: center;  border: 1px solid;}table {  border-collapse: collapse;  margin-top: 10px;}

Timeouts in inactive tabs

To reduce the load (and associated battery usage) from background tabs, browsers will enforcea minimum timeout delay in inactive tabs. It may also be waived if a page is playing soundusing a Web Audio APIAudioContext.

The specifics of this are browser-dependent:

  • Firefox Desktop has a minimum timeout of 1 second for inactive tabs.

  • Firefox for Android has a minimum timeout of 15 minutes for inactive tabs and may unload them entirely.

  • Firefox does not throttle inactive tabs if the tab contains anAudioContext.

  • Chrome uses different levels of throttling depending on the tab activity:

    • Minimal throttling: Applies to timers when the page is visible, has made sound recently, or is otherwise considered active by Chrome. Timers run close to the requested interval.

    • Throttling: Applies to timers when minimal throttle conditions are not met and any of these conditions are true:

      • Nesting count (i.e., number of chained timer calls) is lower than 5.
      • Page has been invisible for less than 5 minutes.
      • WebRTC is active.

    Timers in this state are checked once per second, which may be batched together with other timers that have similar timeouts.

    • Intensive throttling: Introduced in Chrome 88 (January 2021). Applies to timers when neither minimal throttling nor throttling conditions are met, and all of the following conditions are met:
      • Nesting count is 5 or higher.
      • Page has been invisible for more than 5 minutes.
      • Page has been silent for more than 30 seconds.
      • WebRTC is inactive.

    Timers in this state are checked once per minute, which may be batched together with other timers that have similar timeouts.

Throttling of tracking scripts

Firefox enforces additional throttling for scripts that it recognizes as tracking scripts.When running in the foreground, the throttling minimum delay is still 4ms. In background tabs, however,the throttling minimum delay is 10,000 ms, or 10 seconds, which comes into effect 30 seconds after adocument has first loaded.

SeeTracking Protection formore details.

Late timeouts

The timeout can also fire later than expected if the page (or the OS/browser) is busy with other tasks.One important case to note is that the function or code snippet cannot be executed untilthe thread that calledsetTimeout() has terminated. For example:

js
function foo() {  console.log("foo has been called");}setTimeout(foo, 0);console.log("After setTimeout");

Will write to the console:

After setTimeoutfoo has been called

This is because even thoughsetTimeout was called with a delay of zero,it's placed on a queue and scheduled to run at the next opportunity; not immediately.Currently-executing code must complete before functions on the queue are executed, thusthe resulting execution order may not be as expected.

Deferral of timeouts during pageload

Firefox will defer firingsetTimeout() timerswhile the current tab is loading. Firing is deferred until the main thread is deemedidle (similar toWindow.requestIdleCallback()),or until the load event is fired.

WebExtension background pages and timers

InWebExtensions,setTimeout()does not work reliably. Extension authors should use thealarmsAPI instead.

Maximum delay value

Browsers store the delay as a 32-bit signed integer internally. This causes an integeroverflow when using delays larger than 2,147,483,647 ms (about 24.8 days). So for example, this code:

js
setTimeout(() => console.log("hi!"), 2 ** 32 - 5000);

…results in the timeout being executed immediately (since2**32 - 5000 overflows to a negative number), while the following code:

js
setTimeout(() => console.log("hi!"), 2 ** 32 + 5000);

…results in the timeout being executed after approximately 5 seconds.

Note: That doesn't matchsetTimeout behavior in Node.js, where any timeout larger than 2,147,483,647 msresults in an immediate execution.

Examples

Setting and clearing timeouts

The following example sets up two simple buttons in a web page and hooks them to thesetTimeout() andclearTimeout() routines. Pressing the firstbutton will set a timeout which shows a message after two seconds and stores thetimeout id for use byclearTimeout(). You may optionally cancel thistimeout by pressing on the second button.

HTML

html
<button>Show a message after two seconds</button><button>Cancel message before it happens</button><div></div>

JavaScript

js
let timeoutID;function setOutput(outputContent) {  document.querySelector("#output").textContent = outputContent;}function delayedMessage() {  setOutput("");  timeoutID = setTimeout(setOutput, 2 * 1000, "That was really slow!");}function clearMessage() {  clearTimeout(timeoutID);}document.getElementById("show").addEventListener("click", delayedMessage);document.getElementById("cancel").addEventListener("click", clearMessage);
#output {  padding: 0.5rem 0;}

Result

See also theclearTimeout() example.

Specifications

Specification
HTML
# dom-settimeout-dev

Browser compatibility

See also

Help improve MDN

Learn how to contribute.

This page was last modified on byMDN contributors.


[8]ページ先頭

©2009-2025 Movatter.jp