setInterval() 全域性函式

注意:此功能在Web Workers中可用。

setInterval() 方法在 WindowWorkerGlobalScope 介面上提供,它以固定的時間延遲重複呼叫函式或執行程式碼片段。

此方法返回一個間隔 ID,該 ID 唯一標識間隔,因此您可以稍後透過呼叫 clearInterval() 來將其刪除。

語法

js
setInterval(code)
setInterval(code, delay)

setInterval(func)
setInterval(func, delay)
setInterval(func, delay, arg1)
setInterval(func, delay, arg1, arg2)
setInterval(func, delay, arg1, arg2, /* …, */ argN)

引數

func

每隔 delay 毫秒執行一次的 function。第一次執行發生在 delay 毫秒之後。

code

可選語法允許您包含字串而不是函式,該字串每隔 delay 毫秒編譯並執行一次。由於與使用 eval() 構成安全風險的原因相同,因此不建議使用此語法。

delay 可選

定時器在指定函式或程式碼的每次執行之間應延遲的時間(以毫秒為單位)。如果未指定,則預設為 0。有關允許的 delay 值範圍的詳細資訊,請參見下面的延遲限制

arg1,…,argN 可選

傳遞給由 func 指定的函式的其他引數,一旦定時器到期。

返回值

返回的 intervalID 是一個數字的非零值,它標識由呼叫 setInterval() 建立的定時器;此值可以傳遞給 clearInterval() 以取消間隔。

瞭解 setInterval()setTimeout() 共享相同的 ID 池,並且 clearInterval()clearTimeout() 在技術上可以互換使用,這一點可能會有所幫助。但是,為了清晰起見,您應該儘量始終使它們匹配,以避免在維護程式碼時產生混淆。

注意:delay 引數被轉換為帶符號的 32 位整數。由於它在 IDL 中被指定為帶符號整數,因此這實際上將 delay 限制為 2147483647 毫秒(大約 24.8 天)。

示例

示例 1:基本語法

以下示例演示了 setInterval() 的基本語法。

js
const intervalID = setInterval(myCallback, 500, "Parameter 1", "Parameter 2");

function myCallback(a, b) {
  // Your code here
  // Parameters are purely optional.
  console.log(a);
  console.log(b);
}

示例 2:交替兩種顏色

以下示例每秒呼叫一次 flashtext() 函式,直到按下“停止”按鈕。

HTML

html
<div id="my_box">
  <h3>Hello World</h3>
</div>
<button id="start">Start</button>
<button id="stop">Stop</button>

CSS

css
.go {
  color: green;
}
.stop {
  color: red;
}

JavaScript

js
// variable to store our intervalID
let nIntervId;

function changeColor() {
  // check if an interval has already been set up
  if (!nIntervId) {
    nIntervId = setInterval(flashText, 1000);
  }
}

function flashText() {
  const oElem = document.getElementById("my_box");
  oElem.className = oElem.className === "go" ? "stop" : "go";
}

function stopTextColor() {
  clearInterval(nIntervId);
  // release our intervalID from the variable
  nIntervId = null;
}

document.getElementById("start").addEventListener("click", changeColor);
document.getElementById("stop").addEventListener("click", stopTextColor);

結果

另請參閱:clearInterval()

“this” 問題

當您將方法傳遞給 setInterval() 或任何其他函式時,它將使用錯誤的 this 值被呼叫。此問題在 JavaScript 參考中進行了詳細解釋。

說明

setInterval() 執行的程式碼執行在與呼叫它的函式不同的執行上下文中。因此,被呼叫函式的 this 關鍵字被設定為 window(或 global)物件,它與呼叫 setTimeout 的函式的 this 值不同。請參閱以下示例(它使用 setTimeout() 而不是 setInterval() - 事實上,這兩個定時器的問題都相同)

js
myArray = ["zero", "one", "two"];

myArray.myMethod = function (sProperty) {
  alert(arguments.length > 0 ? this[sProperty] : this);
};

myArray.myMethod(); // prints "zero,one,two"
myArray.myMethod(1); // prints "one"
setTimeout(myArray.myMethod, 1000); // prints "[object Window]" after 1 second
setTimeout(myArray.myMethod, 1500, "1"); // prints "undefined" after 1,5 seconds

// Passing the 'this' object with .call won't work
// because this will change the value of this inside setTimeout itself
// while we want to change the value of this inside myArray.myMethod.
// In fact, it will be an error because setTimeout code expects this to be the window object:
setTimeout.call(myArray, myArray.myMethod, 2000); // error: "NS_ERROR_XPC_BAD_OP_ON_WN_PROTO: Illegal operation on WrappedNative prototype object"
setTimeout.call(myArray, myArray.myMethod, 2500, 2); // same error

如您所見,在舊版 JavaScript 中沒有方法將 this 物件傳遞給回撥函式。

可能的解決方案

所有現代 JavaScript 執行時(在瀏覽器和其他地方)都支援 箭頭函式,以及詞法 this - 如果我們在 myArray 方法內部,則允許我們編寫 setInterval(() => this.myMethod())

如果您需要支援 IE,請使用 Function.prototype.bind() 方法,該方法允許您指定應作為給定函式的所有呼叫的 this 使用的值。這樣可以輕鬆避免在不清楚 this 將是什麼的情況下出現問題,具體取決於呼叫函式的上下文。

使用說明

setInterval() 函式通常用於為重複執行的函式(例如動畫)設定延遲。您可以使用 clearInterval() 取消間隔。

如果您希望在指定的延遲後呼叫一次函式,請使用 setTimeout()

延遲限制

間隔可以巢狀;也就是說,setInterval() 的回撥可以依次呼叫 setInterval() 以啟動另一個間隔執行,即使第一個間隔仍在執行。為了減輕這可能對效能產生的潛在影響,一旦間隔巢狀超過五層,瀏覽器將自動強制執行 4 毫秒的最小值。在深度巢狀的 setInterval() 呼叫中嘗試指定小於 4 毫秒的值將被固定為 4 毫秒。

在某些情況下,瀏覽器可能會強制執行更嚴格的間隔最小值,儘管這些情況應該不常見。還要注意,回撥呼叫之間實際經過的時間可能比給定的 delay 更長;請參閱指定延遲時間過長原因以獲取示例。

確保執行持續時間短於間隔頻率

如果您的邏輯可能需要比間隔時間更長的時間才能執行,建議您使用 setTimeout() 遞迴呼叫命名函式。例如,如果使用 setInterval() 每 5 秒輪詢遠端伺服器一次,則網路延遲、伺服器無響應以及許多其他問題可能會阻止請求在分配的時間內完成。因此,您可能會發現自己擁有排隊的 XHR 請求,這些請求不一定會按順序返回。

在這些情況下,首選遞迴 setTimeout() 模式

js
(function loop() {
  setTimeout(() => {
    // Your logic here

    loop();
  }, delay);
})();

在上面的程式碼片段中,聲明瞭一個命名函式 loop() 並立即執行。在邏輯執行完成後,loop()setTimeout() 中遞迴呼叫。雖然此模式不能保證以固定間隔執行,但它確實保證了在遞迴之前先完成先前的間隔。

規範

規範
HTML 標準
# dom-setinterval-dev

瀏覽器相容性

BCD 表格僅在瀏覽器中載入

另請參閱