Promise.all是并发还是并行执行?NodeJS单线程测试现象求解释
测试结果现象解释
你的基础认知没有错误,这个测试看起来是并行执行的效果,本质是Node.js异步I/O并发的表现,和CPU多核并行不是同一概念,具体原因如下:
- 首先,Promise本身只是异步状态的容器,你代码中的3个Promise在声明
a/b/c变量时,传入Promise构造函数的执行器就已经同步执行了,几乎在同一时间完成了三个2000ms定时器的注册,不需要等到Promise.all调用才开始执行。 - 其次,
setTimeout属于Node.js运行时提供的异步API,计时逻辑完全不占用JS主线程资源,由底层libuv库调用操作系统的定时器能力独立处理,三个定时器会独立计时,到期后才会把回调任务推入JS主线程的事件队列等待执行。 - 最后,你观察到的总耗时≈2s是I/O并发的效果,并没有违背单线程规则:如果把定时器替换为CPU密集型计算任务(比如循环阻塞主线程2s),总耗时会是三个任务的耗时之和,这类计算必须在单线程的JS主线程上排队执行,无法并行,测试代码可参考如下:
// CPU密集型任务测试,总耗时≈6000ms const a = new Promise(resolve => { const start = Date.now() while(Date.now() - start < 2000) {} // 阻塞主线程2s resolve("a") }) const b = new Promise(resolve => { const start = Date.now() while(Date.now() - start < 2000) {} resolve("b") }) const c = new Promise(resolve => { const start = Date.now() while(Date.now() - start < 2000) {} resolve("c") }) const begin = Date.now(); async function test() { const promises = [a, b, c]; const [output1, output2, output3] = await Promise.all(promises); return `done: ${output1} ${output2} ${output3}`; } test().then((res)=>{ console.log(res); console.log( "time :", Date.now()- begin); })
所有JS代码(包括Promise的resolve回调)仍然是在单线程上按顺序执行的,并行的只是操作系统层面的定时器计时逻辑,不属于JS代码的执行范畴。
内容的提问来源于stack exchange,提问作者shady
相关产品推荐
相关产品推荐

