Skip to content

定时器

[稳定: 2 - 稳定]

稳定: 2 稳定性: 2 - 稳定

源代码: lib/timers.js

timer 模块提供了一个全局 API,用于调度函数在未来的某个时间点被调用。因为定时器函数是全局的,所以无需调用 require('node:timers') 来使用该 API。

Node.js 中的定时器函数实现了与 Web 浏览器提供的定时器 API 类似的 API,但是使用了不同的内部实现,该实现基于 Node.js 的 事件循环

类: Immediate

此对象是在内部创建的,并从 setImmediate() 返回。它可以传递给 clearImmediate() 以取消已安排的操作。

默认情况下,当安排一个立即执行的任务时,只要该任务处于活动状态,Node.js 事件循环就会继续运行。setImmediate() 返回的 Immediate 对象同时导出 immediate.ref()immediate.unref() 函数,这些函数可用于控制此默认行为。

immediate.hasRef()

新增于: v11.0.0

如果为 true,则 Immediate 对象将保持 Node.js 事件循环处于活动状态。

immediate.ref()

新增于: v9.7.0

调用此方法时,请求 Node.js 事件循环在 Immediate 对象处于活动状态时 退出。多次调用 immediate.ref() 将不会产生任何影响。

默认情况下,所有 Immediate 对象都被“引用”,因此通常无需调用 immediate.ref(),除非之前已调用 immediate.unref()

immediate.unref()

新增于: v9.7.0

调用此方法时,活动 Immediate 对象将不需要 Node.js 事件循环保持活动状态。如果没有其他活动使事件循环保持运行,则在调用 Immediate 对象的回调函数之前,进程可能会退出。多次调用 immediate.unref() 将不会产生任何影响。

immediate[Symbol.dispose]()

新增于: v20.5.0, v18.18.0

[稳定性: 1 - 实验性]

稳定性: 1 稳定性: 1 - 实验性

取消立即执行任务。这类似于调用 clearImmediate()

类: Timeout

此对象由内部创建,并由 setTimeout()setInterval() 返回。它可以传递给 clearTimeout()clearInterval() 以取消计划的操作。

默认情况下,当使用 setTimeout()setInterval() 安排计时器时,只要计时器处于活动状态,Node.js 事件循环就会继续运行。这些函数返回的每个 Timeout 对象都导出 timeout.ref()timeout.unref() 函数,这些函数可用于控制此默认行为。

timeout.close()

新增于:v0.9.1

[稳定性:3 - 已弃用]

稳定性:3 稳定性:3 - 已弃用:请改用 clearTimeout()

取消超时。

timeout.hasRef()

新增于:v11.0.0

如果为真,则 Timeout 对象将保持 Node.js 事件循环处于活动状态。

timeout.ref()

新增于:v0.9.1

调用此方法时,请求 Node.js 事件循环在 Timeout 对象处于活动状态时 不要 退出。多次调用 timeout.ref() 不会有任何影响。

默认情况下,所有 Timeout 对象都被“引用”,因此通常无需调用 timeout.ref(),除非之前已调用 timeout.unref()

timeout.refresh()

新增于:v10.2.0

将计时器的开始时间设置为当前时间,并重新安排计时器在其回调函数中调用先前指定的时间长度(调整为当前时间)。这对于在不分配新的 JavaScript 对象的情况下刷新计时器非常有用。

对已经调用其回调函数的计时器使用此方法将重新激活计时器。

timeout.unref()

新增于:v0.9.1

调用此方法后,活动的 Timeout 对象将不需要 Node.js 事件循环保持活动状态。如果没有其他活动使事件循环保持运行,则在 Timeout 对象的回调函数被调用之前,进程可能会退出。多次调用 timeout.unref() 不会有任何效果。

timeout[Symbol.toPrimitive]()

新增于:v14.9.0, v12.19.0

  • 返回值:<integer> 一个可用于引用此 timeout 的数字

Timeout 强制转换为基本类型。该基本类型可用于清除 Timeout。该基本类型只能在创建 timeout 的同一线程中使用。因此,要在 worker_threads 之间使用它,必须首先将其传递到正确的线程。这允许与浏览器 setTimeout()setInterval() 实现增强兼容性。

timeout[Symbol.dispose]()

新增于: v20.5.0, v18.18.0

[稳定性: 1 - 实验性]

稳定性: 1 稳定性: 1 - 实验性

取消超时。

定时器调度

Node.js 中的定时器是一个内部构造,它在特定时间段后调用给定的函数。定时器的函数何时被调用取决于用于创建定时器的方法以及 Node.js 事件循环正在执行的其他工作。

setImmediate(callback[, ...args])

[历史]

版本更改
v18.0.0将无效回调传递给 callback 参数现在会抛出 ERR_INVALID_ARG_TYPE 而不是 ERR_INVALID_CALLBACK
v0.9.1新增于: v0.9.1

在 I/O 事件的回调之后调度 callback 的“立即”执行。

当多次调用 setImmediate() 时,callback 函数会按照创建的顺序排队执行。整个回调队列在每次事件循环迭代中都会被处理。如果从正在执行的回调内部排队一个立即定时器,则该定时器直到下一次事件循环迭代才会被触发。

如果 callback 不是函数,则会抛出 TypeError

此方法具有一个用于 Promise 的自定义变体,可以使用 timersPromises.setImmediate() 来访问。

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

[历史]

版本变更
v18.0.0将无效回调传递给 callback 参数现在会抛出 ERR_INVALID_ARG_TYPE 而不是 ERR_INVALID_CALLBACK
v0.0.1添加到:v0.0.1
  • callback <函数> 定时器到期时要调用的函数。
  • delay <数字> 调用 callback 之前要等待的毫秒数。默认值: 1
  • ...args <任意> 调用 callback 时要传递的可选参数。
  • 返回值: <Timeout> 用于 clearInterval()

安排每隔 delay 毫秒重复执行 callback

delay 大于 2147483647 或小于 1 或为 NaN 时,delay 将被设置为 1。非整数延迟将被截断为整数。

如果 callback 不是函数,则会抛出 TypeError

此方法具有一个用于 Promise 的自定义变体,可以使用 timersPromises.setInterval() 使用。

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

[历史]

版本变更
v18.0.0将无效回调传递给 callback 参数现在抛出 ERR_INVALID_ARG_TYPE 而不是 ERR_INVALID_CALLBACK
v0.0.1添加于:v0.0.1
  • callback <函数> 定时器到期时要调用的函数。
  • delay <数字> 调用 callback 之前要等待的毫秒数。默认值: 1
  • ...args <任何> 调用 callback 时要传递的可选参数。
  • 返回值: <超时> 用于与 clearTimeout() 一起使用

delay 毫秒后调度一次性 callback 的执行。

callback 可能不会在精确的 delay 毫秒后被调用。Node.js 并不保证回调触发的确切时间,也不保证它们的顺序。回调将在尽可能接近指定的时间点被调用。

delay 大于 2147483647 或小于 1NaN 时,delay 将被设置为 1。非整数延迟将被截断为整数。

如果 callback 不是函数,则会抛出 TypeError

此方法具有使用 timersPromises.setTimeout() 可用的 Promise 自定义变体。

取消定时器

setImmediate()setInterval()setTimeout() 方法分别返回表示已调度定时器的对象。这些对象可以用来取消定时器并阻止其触发。

对于 setImmediate()setTimeout() 的 Promise 版本,可以使用 AbortController 来取消定时器。取消时,返回的 Promise 将会以 'AbortError' 拒绝。

对于 setImmediate()

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

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

// 我们没有 `await` promise,因此 `ac.abort()` 是并发调用的。
setImmediatePromise('foobar', { signal })
  .then(console.log)
  .catch(err => {
    if (err.name === 'AbortError') console.error('The immediate was aborted')
  })

ac.abort()
js
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()

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

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

// 我们没有 `await` promise,因此 `ac.abort()` 是并发调用的。
setTimeoutPromise(1000, 'foobar', { signal })
  .then(console.log)
  .catch(err => {
    if (err.name === 'AbortError') console.error('The timeout was aborted')
  })

ac.abort()
js
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)

新增于:v0.9.1

取消由 setImmediate() 创建的 Immediate 对象。

clearInterval(timeout)

新增于:v0.0.1

取消由 setInterval() 创建的 Timeout 对象。

clearTimeout(timeout)

新增于:v0.0.1

取消由 setTimeout() 创建的 Timeout 对象。

定时器 Promises API

[历史]

版本变更
v16.0.0从实验性功能毕业。
v15.0.0在 v15.0.0 版本中添加

timers/promises API 提供了一组返回 Promise 对象的替代定时器函数。该 API 可通过 require('node:timers/promises') 访问。

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

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

新增于: v15.0.0

  • delay <number> 等待 promise 完成之前的毫秒数。默认值: 1
  • value <any> promise 完成时返回的值。
  • options <Object>
    • ref <boolean> 设置为 false 表示计划的 Timeout 不需要 Node.js 事件循环保持活动状态。默认值: true
    • signal <AbortSignal> 可选的 AbortSignal,用于取消计划的 Timeout
js
import { setTimeout } from 'node:timers/promises'

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

console.log(res) // 打印 'result'
js
const { setTimeout } = require('node:timers/promises')

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

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

新增于:v15.0.0

  • value <任意> 用于 Promise fulfilled 的值。
  • options <对象>
    • ref <布尔值> 设置为 false 表示计划的 Immediate 不需要 Node.js 事件循环保持活动状态。默认值: true
    • signal <AbortSignal> 可选的 AbortSignal,用于取消计划的 Immediate
js
import { setImmediate } from 'node:timers/promises'

const res = await setImmediate('result')

console.log(res) // 打印 'result'
js
const { setImmediate } = require('node:timers/promises')

setImmediate('result').then(res => {
  console.log(res) // 打印 'result'
})

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

新增于:v15.9.0

返回一个异步迭代器,以 delay 毫秒的间隔生成值。如果 reftrue,则需要显式或隐式调用异步迭代器的 next() 来保持事件循环处于活动状态。

  • delay <number> 迭代之间等待的毫秒数。默认值: 1
  • value <any> 迭代器返回的值。
  • options <Object>
    • ref <boolean> 设置为 false 表示迭代之间的计划 Timeout 不需要 Node.js 事件循环保持活动状态。默认值: true
    • signal <AbortSignal> 可选的 AbortSignal,可用于取消操作之间的计划 Timeout
js
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())
js
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])

新增于:v17.3.0, v16.14.0

[稳定性:1 - 实验性]

稳定性:1 稳定性:1 - 实验性

  • delay <number> 等待毫秒数,之后 promise 将被 resolved。

  • options <Object>

    • ref <boolean> 设置为 false 表示计划的 Timeout 不需要 Node.js 事件循环保持活动状态。默认值: true
    • signal <AbortSignal> 可选的 AbortSignal,用于取消等待。
  • 返回值: <Promise>

一个实验性 API,由正在开发中的标准 Web 平台 API ——调度 API 草案规范定义。

调用 timersPromises.scheduler.wait(delay, options) 等同于调用 timersPromises.setTimeout(delay, undefined, options)

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

await scheduler.wait(1000) // 等待一秒钟后再继续

timersPromises.scheduler.yield()

新增于:v17.3.0, v16.14.0

[稳定性:1 - 实验性]

稳定性:1 稳定性:1 - 实验性

一个实验性 API,由正在开发中的标准 Web 平台 API 调度 API 草案规范定义。

调用 timersPromises.scheduler.yield() 等效于调用不带参数的 timersPromises.setImmediate()