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

JavaScript并行处理Promise:实现超时提前返回前两个完成结果的逻辑

JavaScript并行处理Promise:实现超时提前返回前两个完成结果的逻辑

看起来你已经理清了基本需求,但确实,用Promise.all的话会卡死在等待所有Promise完成,没法实现“超时就提前返回前两个结果”的逻辑。我来帮你调整一下思路和代码:

你原来的代码是等所有Promise都跑完了才判断耗时,这时候已经错过了提前返回的时机——毕竟如果有一个Promise要跑100ms,你得等它跑完才能知道总耗时超过50ms,但这时候用户已经等了100ms了,完全不符合需求里“返回前两个可用结果”的要求。

我们需要换个思路:同时监听两个事件,要么所有Promise在50ms内全部完成,要么超时后立刻去拿前两个完成的结果。下面是完整的实现方案:

function getPromise(): Promise<number> {
  return new Promise(resolve => {
    setTimeout(()=>{
      resolve(Math.round(Math.random() * 10))
    }, Math.random() * 100);
  })
};

// 辅助函数:等待数组中前n个完成的Promise,返回它们的结果数组
function waitForN<T>(promises: Promise<T>[], n: number): Promise<T[]> {
  return new Promise((resolve) => {
    let completedCount = 0;
    const results: T[] = [];

    promises.forEach(promise => {
      promise.then(result => {
        // 只收集前n个完成的结果
        if (completedCount < n) {
          results.push(result);
          completedCount++;
          // 收集够n个就立刻resolve,不等剩下的Promise
          if (completedCount === n) {
            resolve(results);
          }
        }
      });
    });
  });
}

const TIMEOUT_MS = 50;

async function foo(){
  // 同步创建三个Promise,满足第一个要求
  const promises = [getPromise(), getPromise(), getPromise()];

  // 定义一个50ms的超时信号Promise
  const timeoutSignal = new Promise(resolve => {
    setTimeout(() => resolve('timeout'), TIMEOUT_MS);
  });

  try {
    // 让"所有Promise完成"和"超时"两个事件竞争
    const raceWinner = await Promise.race([
      Promise.all(promises), // 所有Promise完成的话,返回结果数组
      timeoutSignal // 超时的话,返回标记字符串
    ]);

    if (raceWinner === 'timeout') {
      // 超时了,等待前两个完成的Promise并返回它们的和
      const firstTwoResults = await waitForN(promises, 2);
      return firstTwoResults.reduce((sum, num) => sum + num, 0);
    } else {
      // 所有Promise都在50ms内完成,返回三个数的总和
      return raceWinner.reduce((sum, num) => sum + num, 0);
    }
  } catch (error) {
    // 处理Promise失败的情况(题目说明都是fulfill,这里可选保留)
    console.error('Promise执行出错:', error);
    throw error;
  }
}

关键逻辑解释:

  1. 同步创建Promise:promises数组是一次性初始化的三个Promise,它们会立刻启动内部的定时器,完全满足“同步创建”的要求。
  2. Promise.race的作用:它会等待第一个完成的Promise——如果三个Promise都在50ms内跑完,Promise.all(promises)会先胜出,我们直接计算总和;如果50ms到了还有Promise没跑完,timeoutSignal先触发,我们就立刻切换到“取前两个结果”的逻辑。
  3. waitForN辅助函数:这个函数会监听所有Promise的完成状态,一旦收集到前N个结果就立刻resolve,不会等待剩下的Promise,完美契合“返回前两个可用结果”的需求。

你可以测试两种场景:

  • 当三个Promise的定时器都小于50ms时,会直接返回三个数的总和;
  • 当有一个或多个Promise的定时器超过50ms时,超时信号会先触发,随后返回前两个完成的Promise的结果之和。

备注:内容来源于stack exchange,提问作者Evanss

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 13:44:34