Node.js:如何发送指定数量请求并计算平均响应时间
如何在Node.js中计算多个HTTP请求的平均响应时间?
首先明确说:你完全不需要用setTimeout来计算真实的请求响应时间,这个函数在这里是多余的——真实的耗时应该是从发起请求的那一刻,到你收到服务器响应的那一刻的时间差,直接在请求前后记录时间就可以了。
接下来我帮你重构代码,实现传入X个请求数、收集所有响应时间、计算平均值的功能:
问题分析
你的原代码有几个小问题:
start的位置不对:应该在发起fetchUrl请求之前记录开始时间,不然计时会包含回调等待的时间,不是真实的请求耗时。- 只处理了单个请求:没有循环发起X次请求的逻辑。
responseTimes和count的作用域错误:放在回调函数里的话,每次请求都会重新初始化,无法累加数据。
方案1:基于回调的实现(适配你的现有代码风格)
var fetchUrl = require("fetch").fetchUrl; function calculateAvgResponseTime(requestCount) { const responseTimes = []; let completedRequests = 0; for (let i = 0; i < requestCount; i++) { // 发起请求前记录开始时间 const start = Date.now(); fetchUrl("http://date.jsontest.com", function(error, meta, body) { if (error) { console.error(`请求 ${i+1} 失败:`, error); completedRequests++; } else { // 计算本次请求耗时(毫秒) const duration = Date.now() - start; responseTimes.push(duration); console.log(`请求 ${i+1} 响应时间: ${duration}ms`); completedRequests++; } // 所有请求完成后计算平均值 if (completedRequests === requestCount) { const total = responseTimes.reduce((sum, time) => sum + time, 0); const avg = total / responseTimes.length; console.log(`\n总请求数: ${requestCount}`); console.log(`所有响应时间: ${responseTimes.join(', ')}ms`); console.log(`平均响应时间: ${avg.toFixed(2)}ms`); } }); } } // 调用示例:传入请求数X,比如5 calculateAvgResponseTime(5);
方案2:基于Promise/Async-Await的实现(更简洁,Node.js v8.9.4支持)
因为Node.js v8.9.4已经支持async/await,我们可以把fetchUrl包装成Promise,让代码更易读:
var fetchUrl = require("fetch").fetchUrl; // 把fetchUrl包装成Promise function fetchWithTiming(url) { return new Promise((resolve, reject) => { const start = Date.now(); fetchUrl(url, (error, meta, body) => { if (error) { reject(error); } else { const duration = Date.now() - start; resolve(duration); } }); }); } async function calculateAvgResponseTime(requestCount) { const promises = []; // 批量创建请求Promise for (let i = 0; i < requestCount; i++) { promises.push(fetchWithTiming("http://date.jsontest.com")); } try { // 等待所有请求完成,获取所有响应时间 const responseTimes = await Promise.all(promises); const total = responseTimes.reduce((sum, time) => sum + time, 0); const avg = total / responseTimes.length; console.log(`总请求数: ${requestCount}`); console.log(`所有响应时间: ${responseTimes.join(', ')}ms`); console.log(`平均响应时间: ${avg.toFixed(2)}ms`); } catch (error) { console.error("请求过程中出错:", error); } } // 调用示例 calculateAvgResponseTime(5);
关键说明
为什么不用setTimeout?
原代码里的setTimeout是用来模拟执行时间,但我们需要的是真实的HTTP请求响应耗时——从发送请求到接收完响应的时间,所以直接在请求前后用Date.now()(比new Date()更高效)计算差值就可以了,完全不需要模拟。累加与平均值计算
我们用数组responseTimes存储每次请求的耗时,等所有请求完成后:- 用
reduce方法累加所有时间得到总和 - 总和除以数组长度(成功的请求数)就是平均响应时间
- 用
关于请求并发
上面的代码是并发发起所有请求,如果需要串行发起(一个接一个),可以在async/await方案里用for...of循环代替批量创建Promise。
内容的提问来源于stack exchange,提问作者colin_dev256
相关产品推荐
相关产品推荐

