探索 JavaScript 定时器

setTimeout()

在编写 JavaScript 代码时,您可能想要延迟函数的执行。

这是setTimeout的工作。 您指定一个回调函数稍后执行,并指定一个值(以毫秒为单位)表示您希望它运行的延迟时间。

setTimeout(() => {
  // runs after 2 seconds
}, 2000);

setTimeout(() => {
  // runs after 50 milliseconds
}, 50);

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

const myFunction = (firstParam, secondParam) => {
  // do something
};

// runs after 2 seconds
setTimeout(myFunction, 2000, firstParam, secondParam);

setTimeout 返回计时器 id。 通常不使用此 id,但您可以存储此 id,如果您想删除此计划的函数执行,可以清除它。

const id = setTimeout(() => {
  // should run after 2 seconds
}, 2000);

// I changed my mind
clearTimeout(id);

零延迟

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

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

console.log(' before ');

此代码将打印

before
after

通过在调度程序中对函数进行排队,这对于避免 CPU 在密集任务上阻塞,并在执行繁重计算时让其他函数执行尤其有用。

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

setInterval()

setInterval 是一个类似于 setTimeout 的函数,但有一个区别:它不会运行一次回调函数,而是在您指定的特定时间间隔(以毫秒为单位)永远运行它。

setInterval(() => {
  // runs every 2 seconds
}, 2000);

上面的函数每 2 秒运行一次,除非您使用 clearInterval 告诉它停止,并将 setInterval 返回的间隔 ID 传递给它。

const id = setInterval(() => {
  // runs every 2 seconds
}, 2000);

clearInterval(id);

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

const interval = setInterval(() => {
  if (App.somethingIWait === 'arrived') {
    clearInterval(interval);
  }
  // otherwise do things
}, 100);

递归 setTimeout

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

如果一个函数总是花费相同的时间,那一切都很好。

setInterval working fine

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

setInterval varying duration

并且可能一个长时间的执行与下一个执行重叠。

setInterval overlapping

为避免这种情况,您可以计划一个递归 setTimeout,使其在回调函数完成后被调用。

const myFunction = () => {
  // do something

  setTimeout(myFunction, 1000);
};

setTimeout(myFunction, 1000);

以实现此方案

Recursive setTimeout

setTimeoutsetInterval 在 Node.js 中可通过 Timers 模块获得。

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