You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何我的Promise队列失效?Promise不resolve陷入循环卡顿

问题原因分析

你的代码出现卡死的核心原因是同步while循环阻塞了JavaScript的事件循环,导致Promise的resolve回调和setTimeout根本没有执行机会,具体拆解如下:

  1. 单线程执行逻辑冲突
    JavaScript是单线程的,同步代码会优先占据主线程执行。你的外层while (tasks > 0)是同步循环,会一直重复执行,完全不给异步任务(Promise的then回调、setTimeout)进入主线程的机会。
    当promisePool达到10之后,内层循环停止,外层循环就会无限重复检查tasks > 0,但此时异步回调里的promisePool--根本没机会执行,promisePool永远不会下降,内层循环再也不会创建新的Promise,程序彻底卡死。

  2. 变量拼写错误
    内层循环的条件里写了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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 16:40:19