Node.js使用Promise.all运行异步函数仍串行,批量并行处理如何实现
问题1:内部4个异步函数调用Promise.all后总耗时仍为各函数耗时之和
原因排查:
- 首先确认你的
this.invariables/this.nouns等方法是否为真异步函数:如果只是加了async关键字修饰、内部全是CPU密集型同步计算逻辑,没有IO操作(查库/调接口/读文件等),那么这些函数的执行逻辑本身会在主线程同步运行:调用第一个函数时会阻塞主线程直到它执行完,才会调用第二个函数,总耗时自然是各函数耗时相加,这种场景下Promise.all无法实现并行,因为JavaScript主线程同一时间只能跑一段同步代码。 - 如果函数内部确实有IO操作,排查是否有底层资源限制:比如数据库连接池最大连接数设为1、第三方接口限流等,导致多个异步请求排队执行,看起来和串行效果一致。
对应解决方法:
- 如果是CPU密集型计算场景:改用
worker_threads模块启动多线程并行执行计算任务。 - 如果是资源限制导致的排队:调整对应资源的并发上限(比如调大数据库连接池大小)即可。
问题2:遍历propositions调用方法时出现串行执行的问题
错误原因:
你的代码把await逻辑嵌套在了生成Promise的循环内部,每生成一个processPropositions的Promise就马上await它执行完成,才会进入下一轮循环生成下一个Promise,相当于所有任务是串行启动的,自然变成串行执行。
正确实现方法:
先一次性启动所有异步任务生成Promise数组,再用Promise.all统一等待所有任务执行完成,最后遍历结果处理逻辑即可,示例代码如下:
// 1. 批量启动所有processPropositions任务,所有异步任务此时已经开始并行执行 const taskPromises = propositions.map(proposition => this.processPropositions(proposition)) // 2. 等待所有异步任务全部执行完成,拿到按顺序排列的结果数组 const taskResults = await Promise.all(taskPromises) // 3. 遍历结果处理连词拼接逻辑 const dataWords = [] taskResults.forEach((result, index) => { dataWords.push(result) if (propositions.length > 1 && index < conjunctions.length) { dataWords.push(Conjunctions.getConjunction(conjunctions[index])) } })
这个写法总耗时等于所有processPropositions任务中耗时最长的那个的耗时,是真正的并行执行。
内容的提问来源于stack exchange,提问作者Igor Cantele
相关产品推荐
相关产品推荐

