我试图写一个简单的承诺队列函数,该函数将处理50个任务与10个并发承诺:
const sendTasks = () => {
let tasks = 50;
const concurrentCount = 10;
let promisePool = 0;
while (tasks > 0) {
console.log(`current tasks: ${tasks}`);
while (promisePool < concurrentCount && task > 0) {
console.log("create promise");
tasks--;
promisePool++;
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("haha");
}, Math.floor(Math.random() * 3) * 1000);
});
promise.then((value) => {
console.log(value);
promisePool--;
});
console.log(`current promisePool: ${promisePool}`);
}
}
return "done";
};
但是当我执行它的时候,承诺似乎永远不会解决,然后一直停留在task〉0 while循环中,有人能给我解释一下为什么承诺永远不会解决吗?
2条答案
按热度按时间zphenhs41#
同步函数内的
while
循环永远不会向Promise.then
或任何其他对象生成控制流。您需要重新调整代码结构,以等待Promise解析,而不会完全终止sendTasks
函数,也不会阻塞引擎。一种方法是将每个Promises推送到一个数组中,然后在该数组上等待
Promise.any
。当Promises完成时,让它们自己从数组中移除,并递归地将更多的Promises推送到数组中。然后在数组中不再存在Promises时返回。z31licg02#
JavaScript是单线程的,除非它明确地不是(Web工作者、节点多处理,... -不承诺),所以
while (tasks > 0) {
是一个忙碌的循环,它永远不会将控制返回给任何事件循环,并给定时器触发的机会。您需要为您的承诺给予一个函数(
.then
)或延续(async/await),以便您可以退回到事件循环并被告知何时继续处理。