Promise实际是并行还是串行执行?代码示例引发的执行时间疑问
关于Promise.all执行时间的疑问解答
你的问题核心在于对Promise“并行”的理解偏差,以及代码里的同步逻辑导致的执行顺序问题:
为什么你的代码里f1和f2是串行执行的?
JavaScript是单线程语言,所有同步代码都必须在主线程里按顺序执行。你写的f1和f2虽然是async函数,但里面的for循环是纯同步阻塞代码——当你调用f1()和f2()时,这两个函数会立刻执行内部的同步逻辑:先跑完f1的100次循环,再跑f2的100次循环,主线程根本没有机会同时处理两个循环。
Promise.all的作用是等待多个异步任务完成,但它没法让同步代码并行。你的代码里f1和f2返回的Promise其实是立即resolved的(因为没有await任何异步操作),所以Promise.all只是在等这两个同步函数执行完毕而已。
为什么main的时间比f1+f2还长?
除了两个函数的同步执行时间,main的时间还包含了这些额外开销:
- async函数创建Promise对象的初始化成本
- Promise.all的调度、等待逻辑的运行时间
- console.time本身的精度误差(毫秒级的计时本身就有波动)
这些额外成本加起来,就会让main的总时间看起来比f1和f2的时间之和更长。
怎么实现真正的并行?
要让Promise.all发挥并行的作用,需要把同步逻辑改成异步操作(比如定时器、网络请求、文件读写等),这些异步操作会被放到事件队列里,主线程可以同时调度多个异步任务:
async function f1(){ console.time("f1"); // 用setTimeout模拟异步任务 await new Promise(resolve => setTimeout(resolve, 100)); console.timeEnd("f1"); } async function f2(){ console.time("f2"); await new Promise(resolve => setTimeout(resolve, 150)); console.timeEnd("f2"); } async function main(){ console.time("main"); await Promise.all([f1(), f2()]) console.timeEnd("main"); } main();
这个时候的输出会类似:
f1: 101.234ms f2: 152.567ms main: 153.123ms
main的时间会接近耗时最长的那个异步任务(f2的150ms),这才是Promise.all真正的并行效果——两个异步任务同时在后台等待,主线程不用阻塞等待其中一个完成再启动另一个。
关键总结
- JavaScript单线程决定了同步代码永远串行,没法并行执行
- Promise.all的“并行”是指异步任务的并行调度,而非同步逻辑的并行
- async函数里只有遇到
await后面的异步操作时,才会让出主线程给其他任务
内容的提问来源于stack exchange,提问作者Rakesh Kumar Sharma
相关产品推荐
相关产品推荐

