使用Promise和async/await实现并发控制,通过维护运行中任务数与等待队列,确保不超过最大并发数,失败请求通过catch捕获并可扩展重试机制,支持动态调整并发上限。

JavaScript 实现并发控制的请求队列,核心在于限制同时进行的请求数量,防止资源过度消耗。通常使用 Promise 和 async/await 来实现。
解决方案
实现思路是维护一个请求队列,并设置一个最大并发数。每当有新的请求加入队列,如果当前并发数小于最大并发数,则立即执行该请求;否则,将其放入等待队列,直到有请求完成释放资源。
class ConcurrentQueue {
constructor(maxConcurrency) {
this.maxConcurrency = maxConcurrency;
this.running = 0;
this.queue = [];
}
enqueue(task) {
return new Promise((resolve, reject) => {
this.queue.push({ task, resolve, reject });
this.run();
});
}
run() {
while (this.running < this.maxConcurrency && this.queue.length) {
const { task, resolve, reject } = this.queue.shift();
this.running++;
task()
.then(resolve)
.catch(reject)
.finally(() => {
this.running--;
this.run(); // 执行下一个任务
});
}
}
}
// 示例
const queue = new ConcurrentQueue(3); // 最大并发数为 3
const fetchData = (url) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
const random = Math.random();
if (random > 0.2) {
console.log(`Fetching ${url} completed`);
resolve(`Data from ${url}`);
} else {
console.error(`Fetching ${url} failed`);
reject(`Failed to fetch ${url}`);
}
}, Math.random() * 1000); // 模拟网络延迟
});
};
const urls = [
"https://example.com/1",
"https://example.com/2",
"https://example.com/3",
"https://example.com/4",
"https://example.com/5",
"https://example.com/6",
];
urls.forEach(url => {
queue.enqueue(() => fetchData(url))
.then(data => console.log("Result:", data))
.catch(error => console.error("Error:", error));
});这个例子中,ConcurrentQueue 类维护了一个请求队列 queue 和一个当前运行的请求数 running。 enqueue 方法将请求封装成 Promise,并将其放入队列。 run 方法负责从队列中取出任务并执行,直到达到最大并发数。 使用 finally 确保请求完成后减少 running 并尝试执行下一个任务。
立即学习“Java免费学习笔记(深入)”;
如何处理请求失败的情况?
请求失败的处理至关重要,不能简单地忽略。在上面的例子中,已经使用了 try...catch 块来捕获 fetchData 中可能出现的错误,并通过 reject 将错误传递给 Promise。更进一步,可以考虑重试机制,在请求失败后自动重新发起请求,或者提供一个错误处理函数,允许用户自定义错误处理逻辑。例如:
task()
.then(resolve)
.catch(error => {
console.error(`Task failed: ${error}`);
reject(error); // 将错误传递给 Promise
})
.finally(() => {
this.running--;
this.run(); // 执行下一个任务
});如何动态调整最大并发数?
在某些场景下,可能需要根据系统负载或网络状况动态调整最大并发数。这可以通过暴露一个 setMaxConcurrency 方法来实现:
setMaxConcurrency(newMaxConcurrency) {
this.maxConcurrency = newMaxConcurrency;
this.run(); // 尝试启动更多任务
}然后,可以在外部根据需要调用 setMaxConcurrency 方法来调整并发数。例如,可以监听系统 CPU 使用率,当 CPU 使用率过高时,降低并发数;当 CPU 使用率较低时,增加并发数。 这种动态调整策略可以更好地适应不同的运行环境,提高系统的整体性能。
除了 Promise,还有其他实现方式吗?
虽然 Promise 和 async/await 是实现并发控制的常用方式,但并非唯一选择。 还可以使用回调函数、生成器函数等方式来实现。 使用回调函数的方式可能比较繁琐,容易陷入回调地狱。 使用生成器函数可以实现更优雅的异步控制,但需要借助一些库(如 co)来执行生成器函数。 相对而言,Promise 和 async/await 的语法更加简洁易懂,更适合现代 JavaScript 开发。
以上就是如何用JavaScript实现一个支持并发控制的请求队列?的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号