Node.js异步代码执行结果不符合预期,对事件循环机制存在疑问
核心问题:你的time工具函数存在参数错误
你定义time函数时,setTimeout的第二个延迟参数错误传入了函数对象time,而非接收的形参ms:
// 错误写法 setTimeout(resolve,time) // 正确写法应为 setTimeout(resolve, ms)
setTimeout的延迟参数如果传入非数值类型,会被隐式转换为数字,函数对象转数字的结果为NaN,此时setTimeout会默认使用最小延迟(浏览器端约4ms,Node.js端约1ms)执行回调,也就是说你写的time(2000)、time(1000)实际都是立刻resolve,没有你预期的等待效果,这是输出不符合预期的最主要原因。
事件循环理解偏差纠正
除了代码写错的问题,你对事件循环的任务优先级判断也有误差:
- 同步代码优先级最高,最先执行
Promise的then/await回调属于微任务,当前宏任务的同步代码执行完后,会先清空全部微任务,再处理宏任务队列里的任务setTimeout回调属于宏任务,即使设置的延迟时间很短,也要等当前所有微任务执行完才会触发
第一次测试场景(setTimeout(()=> console.log("b"),10))解释
你预期b先于hi输出,是错误假设time(2000)会等待2秒。实际time函数几乎立刻resolve,同步代码输出a后,微任务队列里的foo函数执行逻辑会优先执行,连续输出hi、hello,此时微任务队列清空,才会轮到宏任务队列里的b输出,最后输出bar,和你拿到的实际结果一致。
第二次测试场景(setTimeout(()=> console.log("b"),3000))解释
你预期b在hi和hello中间输出,还是基于错误的time函数延迟预期。实际foo里的三个await对应的微任务会连续执行,依次输出hi、hello、bar,全部微任务处理完后,才会等到3000ms触发setTimeout回调输出b,和你拿到的实际结果一致。
内容的提问来源于stack exchange,提问作者iceman harden
相关产品推荐
相关产品推荐

