JavaScript中async循环内累加异步调用结果的写法是否合法?有没有更优方案?
现有写法可用性判断
你的写法逻辑完全正确,可以正常运行,它会串行执行所有异步请求,按顺序拿到每个返回值累加,最终可以得到准确的求和结果。
但这种写法的性能非常差:所有请求是挨个执行的,总耗时等于所有单个请求耗时的总和,当ids数量较多时,等待时间会成倍增长。
性能更优的实现方案
推荐使用Promise.all并行发起所有请求,总耗时仅等于耗时最长的单个请求的耗时,相比串行写法性能提升非常明显:
// 批量生成所有请求的Promise const promiseList = ids.map(id => getRes(id)) // 等待所有请求执行完成拿到结果数组 const resList = await Promise.all(promiseList) // 对结果数组求和 const sum = resList.reduce((prev, curr) => prev + curr, 0)
特殊场景适配方案
如果遇到接口有并发限流、或者浏览器同域名并发请求数限制的情况,可以做分批次并发控制,既保证性能又不会触发限制,示例如下:
const maxConcurrency = 5 // 可根据实际情况调整并发数 let sum = 0 for (let i = 0; i < ids.length; i += maxConcurrency) { // 每次取最多maxConcurrency个id发起请求 const batchIds = ids.slice(i, i + maxConcurrency) const batchRes = await Promise.all(batchIds.map(id => getRes(id))) sum += batchRes.reduce((prev, curr) => prev + curr, 0) }
如果允许部分请求失败的场景下依然能对成功的结果求和,可以把Promise.all替换为Promise.allSettled,过滤出成功状态的结果再累加即可。
内容的提问来源于stack exchange,提问作者jason135
相关产品推荐
相关产品推荐

