计时器回调作为 NodeJS 事件循环的一部分执行。当您致电setTimeout或setInterval时,libuv(实现 NodeJS 事件循环的 C 库)会在“最小堆”数据结构(称为计时器堆)中创建一个计时器。在此数据结构中,它跟踪每个计时器到期的时间戳。
在事件循环的每次新迭代开始时,libuv 调用uv__update_time依次调用系统调用来获取当前时间并将当前循环时间更新到毫秒精度。(https://github.com/nodejs/node/blob/master/deps/uv/src/unix/core.c#L375)
该步骤之后就是事件循环迭代的第一个主要阶段,即计时器阶段。在这个阶段,libuv调用uv__run_timers处理所有过期定时器的回调。在此阶段,libuv 遍历计时器堆,根据刚刚更新的“循环时间”来识别过期计时器uv__update_time。然后它调用所有过期计时器的回调。
以下是 NodeJS 中事件循环实现的一个经过编辑的片段,以突出显示我刚才描述的内容。
while (r != 0 && loop->stop_flag == 0) {
uv__update_time(loop);
uv__run_timers(loop);
// ...redacted for brevity...
r = uv__loop_alive(loop);
if (mode == UV_RUN_ONCE || mode == UV_RUN_NOWAIT)
break;
}
Run Code Online (Sandbox Code Playgroud)
我不久前写了一系列关于 NodeJS 事件循环的文章。我希望该系列的这篇文章会对您有所帮助。https://blog.insiderattack.net/timers-immediates-and-process-nexttick-nodejs-event-loop-part-2-2c53fd511bb3
| 归档时间: |
|
| 查看次数: |
1765 次 |
| 最近记录: |