Skip to content

探索 JavaScript 定时器

setTimeout()

编写 JavaScript 代码时,你可能希望延迟函数的执行。

这就是 setTimeout 的作用。你指定一个稍后执行的回调函数,以及一个表示稍后执行时间的值(以毫秒为单位):

js
setTimeout(() => {
  // 2 秒后运行
}, 2000)
setTimeout(() => {
  // 50 毫秒后运行
}, 50)

此语法定义了一个新函数。你可以在其中调用任何其他函数,或者传递现有的函数名称和一组参数:

js
const myFunction = (firstParam, secondParam) => {
  // 执行某些操作
}
// 2 秒后运行
setTimeout(myFunction, 2000, firstParam, secondParam)

setTimeout 返回定时器 ID。这通常不会使用,但是你可以存储此 ID,如果要删除此计划的函数执行,则可以清除它:

js
const id = setTimeout(() => {
  // 应该在 2 秒后运行
}, 2000)
// 我改变主意了
clearTimeout(id)

零延迟

如果将超时延迟指定为 0,则回调函数将在当前函数执行之后尽快执行:

js
setTimeout(() => {
  console.log('after ')
}, 0)
console.log(' before ')

这段代码将打印

bash
before
after

这在避免 CPU 在密集型任务上阻塞并让其他函数在执行繁重计算时执行非常有用,方法是将函数排队到调度程序中。

TIP

一些浏览器(IE 和 Edge)实现了 setImmediate() 方法,该方法具有完全相同的功用,但它不是标准的,并且在其他浏览器上不可用。但它是 Node.js 中的标准函数。

setInterval()

setInterval 是一个类似于 setTimeout 的函数,区别在于:它不是只运行回调函数一次,而是会根据您指定的特定时间间隔(以毫秒为单位)无限期地运行它:

js
setInterval(() => {
  // 每 2 秒运行一次
}, 2000)

除非您使用 clearInterval 并传入 setInterval 返回的间隔 ID 来停止它,否则上面的函数将每 2 秒运行一次:

js
const id = setInterval(() => {
  // 每 2 秒运行一次
}, 2000)
// 我改变主意了
clearInterval(id)

通常在 setInterval 回调函数内调用 clearInterval,让它自动确定是否应该再次运行或停止。例如,这段代码运行某些内容,除非 App.somethingIWait 的值为 arrived:

递归 setTimeout

setInterval 每 n 毫秒启动一个函数,而不会考虑函数何时完成执行。

如果函数始终花费相同的时间,那就没问题。

也许函数的执行时间不同,取决于网络状况。

也许一个长时间的执行会与下一个重叠。

为了避免这种情况,你可以在回调函数完成时调度一个递归 setTimeout

js
const myFunction = () => {
  // 执行某些操作
  setTimeout(myFunction, 1000)
}
setTimeout(myFunction, 1000)

setTimeoutsetInterval 可在 Node.js 中通过 Timers 模块 使用。

Node.js 还提供 setImmediate(),它等效于使用 setTimeout(() => {}, 0),主要用于处理 Node.js 事件循环。