探索 JavaScript 定时器
setTimeout()
在编写 JavaScript 代码时,你可能想要延迟一个函数的执行。
这就是 setTimeout 的作用。你指定一个稍后要执行的回调函数,以及一个表示要延迟多久的值,单位为毫秒。
(() => {
// runs after 2 seconds
}, 2000);
(() => {
// runs after 50 milliseconds
}, 50);
此语法定义了一个新函数。你可以在其中调用任何其他你想要的函数,或者你可以传递一个已存在的函数名和一组参数。
const = (, ) => {
// do something
};
// runs after 2 seconds
(, 2000, firstParam, secondParam);
在 Node.js 中,setTimeout 返回一个 Timeout 实例,而在浏览器中它返回一个数字定时器 ID。这个对象或 ID 可以用来取消已计划的函数执行。
const = (() => {
// should run after 2 seconds
}, 2000);
// I changed my mind
();
零延迟
如果你将超时延迟指定为 0,回调函数将尽快执行,但在当前函数执行之后。
(() => {
.('after ');
}, 0);
.(' before ');
这段代码将打印:
before
after
这对于避免在密集型任务上阻塞 CPU 特别有用,它可以通过在调度器中将函数排队,让其他函数在执行繁重计算时得以执行。
一些浏览器(IE 和 Edge)实现了一个
setImmediate()方法,它实现了完全相同的功能,但它不是标准的,并且在其他浏览器上不可用。但它在 Node.js 中是一个标准函数。
setInterval()
setInterval 是一个类似于 setTimeout 的函数,但有一个区别:它不是只运行一次回调函数,而是会以你指定的特定时间间隔(以毫秒为单位)永远运行它。
(() => {
// runs every 2 seconds
}, 2000);
上面的函数每 2 秒运行一次,除非你使用 clearInterval 告诉它停止,并向其传递 setInterval 返回的 interval id。
const = (() => {
// runs every 2 seconds
}, 2000);
();
通常会在 setInterval 回调函数内部调用 clearInterval,让它自动判断是应该再次运行还是停止。例如,这段代码会一直运行某个东西,除非 App.somethingIWait 的值变为 arrived。
const = (() => {
if (App.somethingIWait === 'arrived') {
();
}
// otherwise do things
}, 100);
递归 setTimeout
setInterval 每 n 毫秒启动一个函数,完全不考虑函数何时完成执行。
如果一个函数总是花费相同的时间,那就没问题。
![]()
但也许函数会因网络状况等原因而有不同的执行时间。
![]()
甚至可能一次长时间的执行会与下一次执行重叠。
![]()
为了避免这种情况,你可以在回调函数完成时安排一个递归的 setTimeout 来调用。
const = () => {
// do something
(, 1000);
};
(, 1000);
以实现这种场景
![]()
在 Node.js 中,通过 Timers 模块 提供了 setTimeout 和 setInterval。
Node.js 还提供了 setImmediate(),它等同于使用 setTimeout(() => {}, 0),主要用于与 Node.js 事件循环协同工作。