- 设计方案
- 使用
Promise.allSettled
:
Promise.allSettled
方法接受一个Promise数组作为参数,它会返回一个新的Promise。这个新的Promise在所有输入的Promise都已经被解决(无论是成功还是失败)时才会被解决。
- 示例代码如下:
const axios = require('axios');
const requests = Array.from({ length: 1000 }, (_, i) =>
axios.get(`https://example.com/api/${i}`)
);
Promise.allSettled(requests)
.then(results => {
results.forEach((result, index) => {
if (result.status === 'fulfilled') {
console.log(`Request ${index} success:`, result.value);
} else {
console.log(`Request ${index} failed:`, result.reason);
}
});
// 在这里可以进行整体应用的后续逻辑,即使部分请求失败也不影响
});
- 控制并发数量:
- 使用队列来管理请求,通过设置一个并发限制,确保同时进行的请求数量在合理范围内,避免资源耗尽。例如,可以使用
async - await
结合Promise
来实现。
- 示例代码如下:
const axios = require('axios');
async function sendRequestsWithLimit(requests, limit) {
const results = [];
const queue = requests.slice();
const running = [];
async function processQueue() {
while (queue.length > 0 && running.length < limit) {
const request = queue.shift();
const promise = request();
running.push(promise);
try {
const result = await promise;
results.push({ status: 'fulfilled', value: result });
} catch (error) {
results.push({ status:'rejected', reason: error });
}
running.splice(running.indexOf(promise), 1);
processQueue();
}
}
processQueue();
while (running.length > 0) {
await Promise.race(running);
}
return results;
}
const requests = Array.from({ length: 1000 }, (_, i) => () =>
axios.get(`https://example.com/api/${i}`)
);
sendRequestsWithLimit(requests, 100)
.then(results => {
results.forEach((result, index) => {
if (result.status === 'fulfilled') {
console.log(`Request ${index} success:`, result.value);
} else {
console.log(`Request ${index} failed:`, result.reason);
}
});
});
- 优化资源利用和错误处理性能
- 优化资源利用:
- 设置合理的并发限制:根据服务器的性能和网络状况,调整并发请求的数量。例如,如果服务器的CPU和内存资源有限,减少并发数可以避免系统资源耗尽。通过测试不同的并发限制值,找到一个既能充分利用资源又不影响性能的平衡点。
- 复用HTTP连接:使用
http.Agent
(在axios
中默认会复用连接)来复用TCP连接,减少建立新连接的开销。例如,在axios
中可以通过设置axios.defaults.agent
来定制连接池的行为。
- 优化错误处理性能:
- 快速失败策略:对于一些明显会失败的请求(例如请求的URL格式错误),在请求发起前进行检查并直接标记为失败,避免不必要的网络请求。
- 错误日志处理:将错误信息进行分类和统计,只记录关键的错误信息,避免大量无用的日志输出影响性能。可以使用专门的日志库(如
winston
)来管理日志记录,设置不同的日志级别(如error
、info
等)。