自己实现Promise.all

1. 核心思路

以下是该promiseAll实现的核心思路梳理,采用分步式解析:

1.1 初始化阶段

  • 创建容器const result = []
    预分配结果数组,用于存储每个Promise的解析值。
  • 计数器let completedCount = 0
    必须用let声明,用于统计已完成的Promise数量(原代码const会导致无法递增)。

1.2. 边界处理

  • 空数组检测

    javascript 复制代码
    if (apis.length === 0) {
      resolve(result);
      return; // 立即终止执行
    }

    若输入为空数组,直接同步返回空结果数组(与原生Promise.all行为一致)。

1.3. 遍历处理每个Promise

  • 统一包装Promise.resolve(api)
    通过Promise.resolve强制将非Promise值(如数字、普通对象)转换为Promise,统一处理逻辑。

  • 索引存储result[index] = res
    按原始顺序存储结果(原代码push会导致结果顺序与输入顺序不一致)。

  • 完成计数

    javascript 复制代码
    completedCount++;
    if (completedCount === apis.length) {
      resolve(result);
    }

    只有当完成数等于总Promise数时,才触发整体resolve

1.4. 错误处理

  • 短路机制.catch(reject)
    任一Promise失败时立即调用reject,中断后续处理(符合Promise.all的快速失败特性)。

2. 最终代码

js 复制代码
/**
 * 自定义实现Promise.all功能
 * @param {Array} apis - Promise对象数组(支持非Promise值)
 * @returns {Promise} 返回新Promise,全部成功时resolve结果数组,任一失败立即reject
 */
function promiseAll(apis = []) {
  return new Promise((resolve, reject) => {
    const result = [];
    let completedCount = 0; // 必须用let声明(原代码const会导致无法递增)

    // 空数组直接resolve
    if (apis.length === 0) {
      resolve(result);
      return; // 需立即返回避免继续执行
    }

    apis.forEach((api, index) => {
      // 用Promise.resolve包裹确保处理非Promise值
      Promise.resolve(api)
        .then((res) => {
          // 按原始顺序存储结果(原代码用push会导致顺序错乱)
          result[index] = res;
          completedCount++;
          
          // 全部完成时才resolve(原代码条件错误:count === result.length)
          if (completedCount === apis.length) {
            resolve(result);
          }
        })
        .catch(reject); // 任一失败立即终止
    });
  });
}
相关推荐
熊猫钓鱼6 分钟前
基于Trae CN与TrendsHub快速实现的热点百事通
前端·trae
LIUENG13 分钟前
Vue3 响应式原理
前端·vue.js
讨厌吃蛋黄酥16 分钟前
前端居中九种方式血泪史:面试官最爱问的送命题,我一次性整明白!
前端·css
龙在天19 分钟前
🤩 用Babel自动埋点,原来这么简单!
前端
Hierifer20 分钟前
跨端实现之网络库拦截
前端
随笔记22 分钟前
react-router里的两种路由方式有什么不同
前端·react.js
前端李二牛22 分钟前
异步任务并发控制
前端·javascript
imLix44 分钟前
RunLoop 实现原理
前端·ios
wayman_he_何大民1 小时前
初始机器学习算法 - 关联分析
前端·人工智能
飞飞飞仔1 小时前
别再瞎写提示词了!这份Claude Code优化指南让你效率提升10倍
前端·claude