为何我的Promise队列失效?Promise不resolve陷入循环卡顿
问题原因分析
你的代码出现卡死的核心原因是同步while循环阻塞了JavaScript的事件循环,导致Promise的resolve回调和setTimeout根本没有执行机会,具体拆解如下:
单线程执行逻辑冲突
JavaScript是单线程的,同步代码会优先占据主线程执行。你的外层while (tasks > 0)是同步循环,会一直重复执行,完全不给异步任务(Promise的then回调、setTimeout)进入主线程的机会。
当promisePool达到10之后,内层循环停止,外层循环就会无限重复检查tasks > 0,但此时异步回调里的promisePool--根本没机会执行,promisePool永远不会下降,内层循环再也不会创建新的Promise,程序彻底卡死。变量拼写错误
内层循环的条件里写了task > 0,但你的任务变量是tasks(多了个s),这个错误会导致内层循环第一次执行就因为task未定义而终止,结合你描述的“卡在tasks>0的循环”,推测这可能是笔误,但也是需要修正的问题。
修正方案示例
要实现带并发限制的Promise队列,需要利用异步机制让主线程有机会处理异步任务,比如用async/await结合递归的方式:
const sendTasks = async () => { const totalTasks = 50; const concurrentCount = 10; let completedTasks = 0; let currentRunning = 0; let taskIndex = 0; // 单个任务执行函数 const executeTask = async () => { const taskId = taskIndex++; console.log(`开始执行任务 ${taskId}`); await new Promise(resolve => { setTimeout(() => { resolve(`任务 ${taskId} 完成: haha`); }, Math.floor(Math.random() * 3) * 1000); }).then(result => { console.log(result); completedTasks++; currentRunning--; // 继续启动新任务 if (taskIndex < totalTasks) { executeTask(); } }); }; // 初始化并发任务 while (currentRunning < concurrentCount && taskIndex < totalTasks) { currentRunning++; executeTask(); } // 等待所有任务完成 while (completedTasks < totalTasks) { await new Promise(resolve => setTimeout(resolve, 100)); } console.log("所有任务完成"); return "done"; }; sendTasks();
这个方案通过递归启动新任务,并用async/await让出主线程执行权,让事件循环有机会处理异步回调,同时保证并发数不超过设定的10个。
内容的提问来源于stack exchange,提问作者Suspended
相关产品推荐
相关产品推荐

