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

不使用async/await实现高效Promise队列的方案探讨

实现支持动态添加Promise的队列(无async/await)

核心需求:队列在存在未解析的Promise时,允许持续添加新的Promise;且实现过程不使用async/await语法。

原方案的问题分析

你尝试通过给Promise.all传入自定义可迭代对象的思路无法满足需求,本质原因是**Promise.all会在调用时一次性完成对可迭代对象的遍历**,不会等待后续添加的元素。你的自定义迭代器虽然用了while(true),但第一次遍历结束后,Promise.all已经收集了所有当时队列中的Promise,后续添加的新Promise不会被纳入处理范围。

高效实现方法

方法1:链式Promise递归处理

通过维护一个持续延伸的Promise链,每次添加新Promise时将其追加到链的尾部,最终通过链的完成状态来返回所有结果。

class DynamicPromiseQueue {
  constructor() {
    // 初始化一个已完成的Promise作为链的起点
    this._currentChain = Promise.resolve();
    this._results = [];
  }

  add(promise) {
    // 将新Promise追加到当前链中,完成后记录结果
    this._currentChain = this._currentChain.then(() => {
      return promise.then(result => {
        this._results.push(result);
      });
    });
  }

  all() {
    // 返回最终Promise,等待整个链完成后返回结果数组
    return this._currentChain.then(() => [...this._results]);
  }
}

工作原理:

  • 每次调用add时,新Promise会被链接到现有链的末尾,确保它会在之前的所有Promise完成后执行(此方案为串行处理,若需并行可调整逻辑)。
  • all方法返回的Promise会等待整个链的所有步骤完成,最终返回收集到的所有结果。

方法2:动态并行处理队列

通过递归处理队列,每次用Promise.all处理当前队列中的所有Promise,完成后再处理后续添加的新Promise,实现并行处理且支持动态添加。

class LazyParallelPromiseQueue {
  constructor() {
    this._queue = [];
    this._isProcessing = false;
    this._finalResolve = null;
    this._results = [];
  }

  add(promise) {
    this._queue.push(promise);
    // 若未在处理队列,启动处理流程
    if (!this._isProcessing) {
      this._process();
    }
  }

  _process() {
    this._isProcessing = true;
    // 取出当前队列的所有Promise,清空队列以接收新添加的
    const currentPromises = [...this._queue];
    this._queue = [];

    if (currentPromises.length === 0) {
      // 队列为空时,若有等待的最终Promise则触发resolve
      if (this._finalResolve) {
        this._finalResolve([...this._results]);
        this._finalResolve = null;
      }
      this._isProcessing = false;
      return;
    }

    // 并行处理当前所有Promise
    Promise.all(currentPromises)
      .then(results => {
        this._results.push(...results);
        // 递归处理新添加的Promise
        this._process();
      })
      .catch(error => {
        // 若需处理错误,可在此触发最终Promise的reject
        if (this._finalResolve) {
          this._finalResolve(Promise.reject(error));
          this._finalResolve = null;
        }
        this._isProcessing = false;
      });
  }

  all() {
    return new Promise(resolve => {
      this._finalResolve = resolve;
      // 若队列已空且未在处理,直接返回空结果
      if (!this._isProcessing && this._queue.length === 0) {
        resolve([...this._results]);
      }
    });
  }
}

工作原理:

  • add方法将新Promise加入队列,若未启动处理则触发_process。
  • _process取出当前队列的所有Promise并行处理,完成后收集结果并递归处理后续添加的Promise。
  • all方法返回的Promise会等待所有队列中的Promise(包括后续动态添加的)全部完成后返回结果。

测试示例

以方法2为例,测试动态添加场景:

function timeout(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

const queue = new LazyParallelPromiseQueue();
queue.add(timeout(1000));

setTimeout(() => {
  queue.add(timeout(1000));
  queue.add(timeout(1000));
}, 500);

// 不使用async/await的方式获取结果
queue.all().then(result => {
  console.log(result); // 约2秒后输出 [undefined, undefined, undefined]
});

内容的提问来源于stack exchange,提问作者David Callanan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 18:40:29