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

JavaScript中如何并行运行异步函数,首个resolve后设超时返回结果?

实现带延迟等待的并行Promise处理方案

假设我们有多个调用外部API、响应时间不固定的异步函数:

async function promise1() { /* API 调用 */ }
async function promise2() { /* API 调用 */ }
async function promise3() { /* API 调用 */ }
// ... 直至promiseN

常规的Promise.all()会等待所有Promise完成后返回结果,但我们需要满足以下特殊需求:

  • 并行启动所有Promise
  • 第一个Promise resolve后,等待500毫秒给其他Promise完成时间
  • 超时后忽略未resolve的Promise
  • 结果仅包含超时窗口结束前已resolve的内容;若除首个外的其他Promise在超时前全部完成(无论resolve或reject),则立即返回结果

实现代码

async function runWithGracePeriod(promiseFns) {
  const resultRecords = [];
  let completedPromiseCount = 0;
  let hasFirstResolved = false;
  let graceTimeoutId = null;

  // 等待触发:要么超时,要么所有Promise都完成
  const waitForCompletion = new Promise(resolve => {
    promiseFns.forEach((promiseFn, idx) => {
      promiseFn()
        .then(value => {
          resultRecords[idx] = { type: 'fulfilled', value };
          // 第一个resolve触发后启动500毫秒等待
          if (!hasFirstResolved) {
            hasFirstResolved = true;
            graceTimeoutId = setTimeout(resolve, 500);
          }
        })
        .catch(reason => {
          resultRecords[idx] = { type: 'rejected', reason };
        })
        .finally(() => {
          completedPromiseCount++;
          // 所有Promise都完成时,提前结束等待
          if (completedPromiseCount === promiseFns.length) {
            if (graceTimeoutId) clearTimeout(graceTimeoutId);
            resolve();
          }
        });
    });
  });

  await waitForCompletion;

  // 筛选出所有成功resolve的结果
  return resultRecords
    .filter(record => record?.type === 'fulfilled')
    .map(record => record.value);
}

代码说明

  1. 并行启动Promise:遍历传入的Promise函数数组,立即调用每个函数启动异步任务,确保所有任务并行执行。
  2. 跟踪第一个resolve:当第一个Promise成功resolve时,启动500毫秒的超时定时器,触发等待窗口的结束。
  3. 提前结束逻辑:通过completedPromiseCount统计已完成的Promise数量,当所有Promise都完成时,立即清除定时器并结束等待,无需等到500毫秒超时。
  4. 结果收集:等待结束后,筛选出所有在窗口内成功resolve的结果返回,忽略reject或未完成的Promise。

使用示例

// 传入异步函数数组(注意是函数,不是已执行的Promise)
const targetPromises = [promise1, promise2, promise3];
runWithGracePeriod(targetPromises).then(finalResults => {
  console.log('最终返回的成功结果:', finalResults);
});

特殊情况处理

  • 如果所有Promise都reject:会立即返回空数组,因为所有Promise完成后触发提前结束,筛选后无成功结果。
  • 如果第一个完成的是reject:会继续等待第一个resolve的Promise出现,再启动500毫秒等待窗口;若始终没有Promise resolve,最终返回空数组。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 03:34:54