Node.js并行调用API开展压力测试的代码调整问题咨询
问题解答
原版本使用Promise.all()出现等待所有请求完成的原因
Promise.all()的设计逻辑就是等待所有传入的Promise实例全部变为 fulfilled 状态后才会统一返回结果数组,所以你确实没办法在单个请求完成时就拿到结果打印,你的猜测是正确的。
第二版代码的并行性确认
你优化后的代码确实是并行发起请求的,不会等待前一个请求返回才发起下一个:
- 你在for循环中调用
requestAsync(url)时没有加await关键字,不会阻塞循环执行 - 所有请求会在循环遍历的瞬间几乎同时发起,每个请求的回调函数会在该请求独立完成时触发,打印对应耗时,完全符合你的需求
现有代码存在的可优化点
- 存在笔误:你定义的URL数组变量名是
urls,但循环里用的是dev_urls,运行会报错需要修正 requestAsync返回的Promise没有手动调用resolve()/reject(),会一直处于pending状态,如果后续需要统计所有请求完成的总耗时会无法实现- 缺少错误捕获逻辑,某个请求失败的话没有报错提示
优化后的完整参考代码
import request from 'request' const urls = ["url1", "url2", "url3", "url4"]; var requestAsync = function(url) { return new Promise((resolve, reject) => { request.get({ url : url, time : true },function(err, response){ if (err) { console.error(`请求${url}失败:`, err) return reject(err) } const cost = (response.elapsedTime / 1000).toFixed(3) console.log(`请求${url}完成,耗时 ${cost} 秒`); resolve(response) }); }); }; var getParallelData = async function() { const startTime = performance.now() // 所有请求并行发起 const promiseList = urls.map(url => requestAsync(url)) // 等待所有请求完成后打印总耗时,单请求失败不会中断 await Promise.allSettled(promiseList) const totalCost = ((performance.now() - startTime) / 1000).toFixed(3) console.log(`所有请求执行完毕,总耗时 ${totalCost} 秒`) } getParallelData();
- 这里用
Promise.allSettled()而不是Promise.all(),是因为前者不会因为某个请求失败就直接终止,会等待所有请求结束(不管成功失败),更适合压力测试场景 - 每个请求完成后会立即打印自身耗时,错误也会单独打印提示
内容的提问来源于stack exchange,提问作者user3437721
相关产品推荐
相关产品推荐

