計時器#

穩定度:2 - 穩定

timer 模組公開了一個全域 API,用於排程在未來某個時間點呼叫的函式。由於計時器函式是全域的,因此無需呼叫 require('node:timers') 即可使用此 API。

Node.js 中的計時器函式實作了與 Web 瀏覽器提供的計時器 API 相似的 API,但使用了基於 Node.js 事件迴圈 (Event Loop) 的不同內部實作。

類別: Immediate#

此物件是在內部建立的,並由 setImmediate() 回傳。它可以被傳遞給 clearImmediate() 以取消已排程的動作。

預設情況下,當一個 immediate 被排程時,只要該 immediate 處於活動狀態,Node.js 事件迴圈就會繼續執行。由 setImmediate() 回傳的 Immediate 物件匯出了 immediate.ref()immediate.unref() 函式,可用於控制此預設行為。

immediate.hasRef()#

若為 true,則 Immediate 物件會保持 Node.js 事件迴圈處於活動狀態。

immediate.ref()#

當呼叫時,會請求 Node.js 事件迴圈在 Immediate 處於活動狀態時不要退出。多次呼叫 immediate.ref() 不會有任何效果。

預設情況下,所有的 Immediate 物件都是「已參照 (ref'ed)」的,因此除非之前呼叫過 immediate.unref(),否則通常不需要呼叫 immediate.ref()

immediate.unref()#

當呼叫時,活動的 Immediate 物件將不會要求 Node.js 事件迴圈保持活動狀態。如果沒有其他活動使事件迴圈保持執行,行程可能會在 Immediate 物件的回呼函式被呼叫之前退出。多次呼叫 immediate.unref() 不會有任何效果。

immediate[Symbol.dispose]()#

取消該 immediate。這類似於呼叫 clearImmediate()

類別: Timeout#

此物件是在內部建立的,並由 setTimeout()setInterval() 回傳。它可以被傳遞給 clearTimeout()clearInterval() 以取消已排程的動作。

預設情況下,當使用 setTimeout()setInterval() 排程計時器時,只要計時器處於活動狀態,Node.js 事件迴圈就會繼續執行。這些函式所回傳的每個 Timeout 物件都匯出了 timeout.ref()timeout.unref() 函式,可用於控制此預設行為。

timeout.close()#

穩定度: 3 - 已過時:請改用 clearTimeout()

  • 回傳值: <Timeout>timeout 的參照

取消該 timeout。

timeout.hasRef()#

若為 true,則 Timeout 物件會保持 Node.js 事件迴圈處於活動狀態。

timeout.ref()#

  • 回傳值: <Timeout>timeout 的參照

當呼叫時,會請求 Node.js 事件迴圈在 Timeout 處於活動狀態時不要退出。多次呼叫 timeout.ref() 不會有任何效果。

預設情況下,所有的 Timeout 物件都是「已參照 (ref'ed)」的,因此除非之前呼叫過 timeout.unref(),否則通常不需要呼叫 timeout.ref()

timeout.refresh()#

  • 回傳值: <Timeout>timeout 的參照

將計時器的開始時間設定為當前時間,並重新排程計時器,使其在先前指定的持續時間(調整至當前時間)後呼叫其回呼函式。這對於在不分配新 JavaScript 物件的情況下重新整理計時器非常有用。

對一個已經呼叫過其回呼函式的計時器使用此方法,將會重新啟用該計時器。

timeout.unref()#

  • 回傳值: <Timeout>timeout 的參照

當呼叫時,活動的 Timeout 物件將不會要求 Node.js 事件迴圈保持活動狀態。如果沒有其他活動使事件迴圈保持執行,行程可能會在 Timeout 物件的回呼函式被呼叫之前退出。多次呼叫 timeout.unref() 不會有任何效果。

timeout[Symbol.toPrimitive]()#

  • 回傳值: <integer> 可用於參照此 timeout 的數值

Timeout 強制轉型為基礎型別。該值可用於清除 Timeout。該值只能在建立計時器的同一執行緒中使用。因此,要在 worker_threads 之間使用它,必須先將其傳遞給正確的執行緒。這增強了與瀏覽器 setTimeout()setInterval() 實作的相容性。

timeout[Symbol.dispose]()#

取消該 timeout。

排程計時器#

Node.js 中的計時器是一種內部結構,會在一段時間後呼叫給定的函式。計時器函式何時被呼叫,取決於建立計時器所使用的方法以及 Node.js 事件迴圈正在執行的其他工作。

setImmediate(callback[, ...args])#

在 I/O 事件的回呼之後,排程 callback 的「立即 (immediate)」執行。

當多次呼叫 setImmediate() 時,callback 函式會依照其建立順序放入執行佇列。整個回呼佇列會在每次事件迴圈迭代時被處理。如果一個 immediate 計時器是在正在執行的回呼函式內加入佇列,該計時器要到下一次事件迴圈迭代時才會觸發。

callback 不是函式,則會拋出 TypeError

此方法有一個針對 Promise 的自訂變體,可透過 timersPromises.setImmediate() 使用。

setInterval(callback[, delay[, ...args]])#

  • callback <Function> 當計時器到期時呼叫的函式。
  • delay <number> 呼叫 callback 前等待的毫秒數。預設值: 1
  • ...args <any> 呼叫 callback 時傳入的選擇性參數。
  • 回傳值: <Timeout>clearInterval() 使用

每隔 delay 毫秒排程一次 callback 的重複執行。

delay 大於 2147483647、小於 1 或為 NaN 時,delay 將被設定為 1。非整數的延遲將被截斷為整數。

callback 不是函式,則會拋出 TypeError

此方法有一個針對 Promise 的自訂變體,可透過 timersPromises.setInterval() 使用。

setTimeout(callback[, delay[, ...args]])#

  • callback <Function> 當計時器到期時呼叫的函式。
  • delay <number> 呼叫 callback 前等待的毫秒數。預設值: 1
  • ...args <any> 呼叫 callback 時傳入的選擇性參數。
  • 回傳值: <Timeout>clearTimeout() 使用

delay 毫秒後排程執行一次性的 callback

callback 很可能不會精準地在 delay 毫秒後被呼叫。Node.js 不保證回呼函式觸發的確切時間,也不保證其呼叫順序。回呼函式將會盡可能接近指定的時間被呼叫。

delay 大於 2147483647、小於 1 或為 NaN 時,delay 將被設定為 1。非整數的延遲將被截斷為整數。

callback 不是函式,則會拋出 TypeError

此方法有一個針對 Promise 的自訂變體,可透過 timersPromises.setTimeout() 使用。

取消計時器#

setImmediate()setInterval()setTimeout() 方法各自回傳代表已排程計時器的物件。這些物件可用於取消計時器並防止其觸發。

對於 setImmediate()setTimeout() 的 promisified 變體,可以使用 AbortController 來取消計時器。取消時,回傳的 Promise 將會被 'AbortError' 拒絕。

對於 setImmediate()

import { setImmediate as setImmediatePromise } from 'node:timers/promises';

const ac = new AbortController();
const signal = ac.signal;

// We do not `await` the promise so `ac.abort()` is called concurrently.
setImmediatePromise('foobar', { signal })
  .then(console.log)
  .catch((err) => {
    if (err.name === 'AbortError')
      console.error('The immediate was aborted');
  });

ac.abort();
const { setImmediate: setImmediatePromise } = require('node:timers/promises');

const ac = new AbortController();
const signal = ac.signal;

setImmediatePromise('foobar', { signal })
  .then(console.log)
  .catch((err) => {
    if (err.name === 'AbortError')
      console.error('The immediate was aborted');
  });

ac.abort();

對於 setTimeout()

import { setTimeout as setTimeoutPromise } from 'node:timers/promises';

const ac = new AbortController();
const signal = ac.signal;

// We do not `await` the promise so `ac.abort()` is called concurrently.
setTimeoutPromise(1000, 'foobar', { signal })
  .then(console.log)
  .catch((err) => {
    if (err.name === 'AbortError')
      console.error('The timeout was aborted');
  });

ac.abort();
const { setTimeout: setTimeoutPromise } = require('node:timers/promises');

const ac = new AbortController();
const signal = ac.signal;

setTimeoutPromise(1000, 'foobar', { signal })
  .then(console.log)
  .catch((err) => {
    if (err.name === 'AbortError')
      console.error('The timeout was aborted');
  });

ac.abort();

clearImmediate(immediate)#

取消由 setImmediate() 建立的 Immediate 物件。

clearInterval(timeout)#

取消由 setInterval() 建立的 Timeout 物件。

clearTimeout(timeout)#

取消由 setTimeout() 建立的 Timeout 物件。

計時器 Promise API#

timers/promises API 提供了一組替代的計時器函式,這些函式回傳 Promise 物件。該 API 可透過 require('node:timers/promises') 存取。

import {
  setTimeout,
  setImmediate,
  setInterval,
} from 'node:timers/promises';
const {
  setTimeout,
  setImmediate,
  setInterval,
} = require('node:timers/promises');

timersPromises.setTimeout([delay[, value[, options]]])#

  • delay <number> 在達成 promise 前等待的毫秒數。預設值: 1
  • value <any> 達成 promise 時所使用的值。
  • options <Object>
    • ref <boolean> 設定為 false 以表示排程的 Timeout 不需要保持 Node.js 事件迴圈活動。預設值: true
    • signal <AbortSignal> 可用於取消排程的 Timeout 的選用 AbortSignal
import {
  setTimeout,
} from 'node:timers/promises';

const res = await setTimeout(100, 'result');

console.log(res);  // Prints 'result'
const {
  setTimeout,
} = require('node:timers/promises');

setTimeout(100, 'result').then((res) => {
  console.log(res);  // Prints 'result'
});

timersPromises.setImmediate([value[, options]])#

  • value <any> 達成 promise 時所使用的值。
  • options <Object>
    • ref <boolean> 設定為 false 以表示排程的 Immediate 不需要保持 Node.js 事件迴圈活動。預設值: true
    • signal <AbortSignal> 可用於取消排程的 Immediate 的選用 AbortSignal
import {
  setImmediate,
} from 'node:timers/promises';

const res = await setImmediate('result');

console.log(res);  // Prints 'result'
const {
  setImmediate,
} = require('node:timers/promises');

setImmediate('result').then((res) => {
  console.log(res);  // Prints 'result'
});

timersPromises.setInterval([delay[, value[, options]]])#

回傳一個非同步迭代器,該迭代器以 delay 毫秒的間隔產生值。如果 reftrue,你需要顯式或隱式地呼叫非同步迭代器的 next() 來保持事件迴圈活動。

  • delay <number> 迭代之間等待的毫秒數。預設值: 1
  • value <any> 迭代器所回傳的值。
  • options <Object>
    • ref <boolean> 設定為 false 以表示迭代之間排程的 Timeout 不需要保持 Node.js 事件迴圈活動。預設值: true
    • signal <AbortSignal> 可用於取消操作之間排程的 Timeout 的選用 AbortSignal
import {
  setInterval,
} from 'node:timers/promises';

const interval = 100;
for await (const startTime of setInterval(interval, Date.now())) {
  const now = Date.now();
  console.log(now);
  if ((now - startTime) > 1000)
    break;
}
console.log(Date.now());
const {
  setInterval,
} = require('node:timers/promises');
const interval = 100;

(async function() {
  for await (const startTime of setInterval(interval, Date.now())) {
    const now = Date.now();
    console.log(now);
    if ((now - startTime) > 1000)
      break;
  }
  console.log(Date.now());
})();

timersPromises.scheduler.wait(delay[, options])#

穩定性:1 - 實驗性

  • delay <number> 在解析 promise 前等待的毫秒數。
  • options <Object>
    • ref <boolean> 設定為 false 以表示排程的 Timeout 不需要保持 Node.js 事件迴圈活動。預設值: true
    • signal <AbortSignal> 可用於取消等待的選用 AbortSignal
  • 傳回:<Promise>

這是一個實驗性 API,由正作為標準 Web Platform API 開發的 排程 API (Scheduling APIs) 草案規範所定義。

呼叫 timersPromises.scheduler.wait(delay, options) 等同於呼叫 timersPromises.setTimeout(delay, undefined, options)

import { scheduler } from 'node:timers/promises';

await scheduler.wait(1000); // Wait one second before continuing

timersPromises.scheduler.yield()#

穩定性:1 - 實驗性

這是一個實驗性 API,由正作為標準 Web Platform API 開發的 排程 API (Scheduling APIs) 草案規範所定義。

呼叫 timersPromises.scheduler.yield() 等同於呼叫不帶參數的 timersPromises.setImmediate()