Node.js执行node file.js时为何两次调用uv_run()?
Node.js执行
node file.js时两次调用uv_run()的原因 先看你提供的测试代码:
// file.js setTimeout(() => { console.log('1'); }, 0);
执行node file.js后,Node.js会两次调用libuv的事件循环核心方法uv_run(),原因可以拆解为以下流程:
第一步:初始化与同步代码执行
Node.js启动时先完成V8引擎、libuv事件循环等环境初始化,接着加载并执行file.js的同步代码:调用setTimeout注册回调。注意这里的0ms延迟会被Node.js自动调整为最小可执行延迟(通常是1ms,具体取决于版本和系统),该定时器任务会被交给libuv管理。第一次调用
uv_run():处理定时器任务
同步代码执行完毕后,Node.js首次调用uv_run()启动事件循环:- 事件循环先进入定时器阶段,此时定时器还未到最小延迟,于是转入轮询阶段阻塞等待;
- 当定时器到期后,回到定时器阶段取出并执行
console.log('1')回调; - 回调执行完成后,处理该回调产生的所有微任务(本例无微任务),事件循环暂时暂停。
第二次调用
uv_run():确认无剩余任务
回调执行完毕后,Node.js需要确保没有遗漏的异步任务(比如未触发的定时器、待处理的I/O请求等),于是第二次调用uv_run()。这次事件循环遍历所有阶段后,发现没有任何活跃任务,便退出事件循环,进程随之结束。
这种两次调用的逻辑是Node.js的兜底机制,保证所有已注册的异步任务都有机会被处理,同时避免进程无意义地挂起。
内容的提问来源于stack exchange,提问作者Andres Diaz
相关产品推荐
相关产品推荐

