代码实现
function asyncRequest(id) {
return new Promise((resolve) => {
setTimeout(() => {
console.log(`Request ${id} completed`);
resolve(id);
}, Math.floor(Math.random() * 1000));
});
}
async function sendRequests() {
const totalRequests = 10;
const maxConcurrent = 3;
const requests = Array.from({ length: totalRequests }, (_, i) => i + 1);
const results = [];
let completedCount = 0;
async function processRequest() {
if (completedCount === totalRequests) {
return;
}
const requestId = requests.shift();
try {
const result = await asyncRequest(requestId);
results.push(result);
} finally {
completedCount++;
processRequest();
}
}
const initialPromises = Array.from({ length: Math.min(maxConcurrent, totalRequests) }, processRequest);
await Promise.all(initialPromises);
return results;
}
sendRequests().then((results) => {
console.log('All requests completed with results:', results);
});
性能优化考虑
- 资源合理利用:通过限制并发数量为3,确保系统资源(如网络连接、CPU等)不会因为过多请求而耗尽,在保证任务执行效率的同时,不会对系统造成过大压力。
- 即时补充请求:当一个请求完成后,立即发起新的请求,这样可以充分利用空闲的资源槽位,提高整体任务执行效率,避免资源浪费。
可能存在的风险
- 请求失败处理:上述代码中,对于
asyncRequest
失败的情况没有详细处理,如果请求失败,processRequest
函数会继续执行,可能导致部分请求遗漏,在实际应用中需要对失败的请求进行重试或其他合适的处理。
- 长时间阻塞:如果某个请求执行时间极长,会导致后续请求排队等待时间过长,影响整体任务完成时间。可以考虑设置请求超时机制,避免单个请求长时间占用资源。
- 队列管理:当请求数量非常大时,维护请求队列可能会占用较多内存,需要注意内存管理问题。