手动实现promise的all,race,finally方法

Promise.all

是一个非常有用的工具,它接受一个 Promise 对象数组,并返回一个新的 Promise。当所有输入的 Promise 都成功解决时,新的 Promise 会解决为一个包含所有结果的数组;如果任何一个 Promise 被拒绝,新的 Promise 会立即被拒绝,并返回第一个被拒绝的错误。

javascript 复制代码
 function myPromiseAll(promiseArray) {
        return new Promise((resolve, reject) => {
            //1.参数检查:
            //检查传入的参数是否为数组,如果不是数组,则抛出 TypeError。
          if (!Array.isArray(promiseArray)) {
            return reject(new TypeError("arguments must be an array"))
          }
          //2.初始化:
          //创建一个 results 数组来存储每个 Promise 的结果。
          //初始化 count 计数器,用于记录已经完成的 Promise 数量。
          //获取 promises 数组的总长度 len。
          let result = []
          let count = 0
          const len = promiseArray.length
          //3.特殊情况处理:
          //如果 promises 数组为空,直接返回一个已解决的 Promise,其结果为一个空数组。
          if (len === 0) {
            resolve(result)
          }
        //4.遍历 Promise 数组:
        //使用 for循环 遍历 promises 数组。
        //对每个 Promise 使用 Promise.resolve 确保它是 Promise 对象。
        //使用 then 方法处理每个 Promise 的成功和失败情况:
        //成功时,将结果存储在 results 数组中,并增加 count。
        //如果 count 达到 len,说明所有 Promise 都已成功解决,调用 resolve 方法,传递 results 数组。
        //失败时,立即调用 reject 方法,传递错误信息。
          for (let i = 0; i < len; i++) {
            Promise.resolve(promiseArray[i])
              .then((res) => {
                result[i] = res
                count++
                if (count === len) {
                  resolve(result)
                }
              })
              .catch((err) => reject(err))
          }
        })
      }
      
      
      // 示例代码

const promise1 = Promise.resolve(1);

const promise2 = Promise.resolve(2);

const promise3 = new Promise((resolve) => setTimeout(() => resolve(3), 1000));

const promise4 = Promise.reject('Error');


myPromiseAll([promise1, promise2, promise3])
  .then((results) => {
    console.log('All promises resolved:', results); // 输出: All promises resolved: [1, 2, 3]
  })
  .catch((error) => {
    console.error('An error occurred:', error);
  });


myPromiseAll([promise1, promise2, promise4])
  .then((results) => {
    console.log('All promises resolved:', results);
  })
  .catch((error) => {
    console.error('An error occurred:', error); // 输出: An error occurred: Error
  });

Promise.race

接受一个 Promise 对象数组,并返回一个新的 Promise。新的 Promise 会在第一个输入的 Promise 被解决或拒绝时立即解决或拒绝,其结果或错误信息取决于第一个完成的 Promise。

javascript 复制代码
 function myPromiseRace(promiseArray) {
        return new Promise((resolve, reject) => {
            //1.参数检查:
            //检查传入的参数是否为数组,如果不是数组,则抛出 TypeError。
          if (!Array.isArray(promiseArray)) {
            return reject(new TypeError("arguments must be an array"))
          }
            //2.遍历 Promise 数组:
            //使用 for 循环遍历 promises 数组。
            //对每个 Promise 使用 Promise.resolve 确保它是 Promise 对象。
            //使用 then 方法处理每个 Promise 的成功和失败情况:
            //成功时,立即调用 resolve 方法,传递结果值。
            //失败时,立即调用 reject 方法,传递错误信息。
          for (let i = 0; i < promiseArray.length; i++) {
              //写法一:
            Promise.resolve(promiseArray[i]).then(
              (res) => {
                resolve(res)
              },
              (error) => {
                reject(error)
              }
            )
            //写法二:
            //Promise.resolve(promiseArray[i]).then(resolve, reject)
          }
        })
      }
     
     // 示例代码

const promise1 = Promise.resolve(1);

const promise2 = new Promise((resolve) => setTimeout(() => resolve(2), 1000));

const promise3 = new Promise((resolve) => setTimeout(() => resolve(3), 500));

const promise4 = Promise.reject('Error');


myPromiseRace([promise1, promise2, promise3])
  .then((result) => {
    console.log('First resolved promise:', result); // 输出: First resolved promise: 1
  })
  .catch((error) => {
    console.error('An error occurred:', error);
  });


myPromiseRace([promise2, promise3, promise4])
  .then((result) => {
    console.log('First resolved promise:', result);
  })
  .catch((error) => {
    console.error('An error occurred:', error); // 输出: An error occurred: Error
  });

Promise.finally

用于指定不管 Promise 最终状态如何,都会执行的操作。这个方法通常用于清理工作,比如关闭文件句柄、清除定时器等。

正常使用:

javascript 复制代码
promise
  .then((result) => {
    // 处理已解决的情况
  })
  .catch((error) => {
    // 处理已失败的情况
  })
  .finally(() => {
    // 不管Promise对象最终的状态如何,都会执行的回调函数
  });

手动实现:

javascript 复制代码
function myPromiseFinally(promise, callback) {
        return promise.then(
            //接受两个参数:一个 Promise 对象 promise 和一个回调函数 callback。
            //使用 then 方法分别处理 promise 的成功和失败情况。
            //在成功的情况下,先调用 callback 回调函数,然后返回原始的成功值。
            //在失败的情况下,先调用 callback 回调函数,然后重新抛出原始的错误。
          (value) => Promise.resolve(callback()).then(() => value),
          (error) =>
            Promise.resolve(callback()).then(() => {
              throw error
            })
        )
      }
     
      //示例代码: 
const promise1 = Promise.resolve(1);
const promise2 = new Promise((resolve) => setTimeout(() => resolve(2), 1000));
const promise3 = new Promise((resolve, reject) => setTimeout(() => reject('Error'), 500));

// 成功的情况
myPromiseFinally(promise1, () => {
  console.log('Finally block executed');
}).then((result) => {
  console.log('Result:', result); // 输出: Result: 1
}).catch((error) => {
  console.error('Error:', error);
});

// 延迟成功的情况
myPromiseFinally(promise2, () => {
  console.log('Finally block executed');
}).then((result) => {
  console.log('Result:', result); // 输出: Result: 2
}).catch((error) => {
  console.error('Error:', error);
});

// 失败的情况
myPromiseFinally(promise3, () => {
  console.log('Finally block executed');
}).then((result) => {
  console.log('Result:', result);
}).catch((error) => {
  console.error('Error:', error); // 输出: Error: Error
});
相关推荐
子兮曰22 分钟前
Agency-Agents 深度解析:400+ AI 专家的"梦之队"如何重塑开发工作流
前端·后端·vibecoding
山河木马1 小时前
渲染管线-计算得到gl_Position(顶点着色器)之后续GPU流程
javascript·webgl·图形学
竹林8181 小时前
用 The Graph 查询链上数据实战:从手搓 RPC 到 Subgraph,我的 NFT 项目数据加载快了 10 倍
前端·javascript
妙码生花1 小时前
从 PHP 到 AI + Golang,程序员自救转型手记(十九):点选验证码代码逐行目检
前端·后端·go
Awu12272 小时前
⚡从零开发 Agent CLI(五)实现一个可治理、可扩展的工具系统
前端·人工智能·claude
咪库咪库咪2 小时前
Vue3-生命周期
前端
莪_幻尘3 小时前
你的 AI Skill 越多越蠢?Token 上下文爆炸的求生指南
前端·ai编程
lichenyang4533 小时前
从 has.echo 到异步 API 注册表:一次 ASCF API 回调不触发的排查复盘
前端
林瞅瞅3 小时前
Nuxt3 项目部署 Nginx 防盗链后特定 JS 文件 403 问题修复方案
前端
kyriewen4 小时前
别再每次都 Google 了:我整理了前端日常最常踩的 10 个 Git 坑,附速查表
前端·javascript·git