手动实现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
});
相关推荐
子兮曰6 小时前
OpenClaw入门:从零开始搭建你的私有化AI助手
前端·架构·github
吴仰晖6 小时前
使用github copliot chat的源码学习之Chromium Compositor
前端
1024小神6 小时前
github发布pages的几种状态记录
前端
灰子学技术7 小时前
go response.Body.close()导致连接异常处理
开发语言·后端·golang
二十雨辰8 小时前
[python]-AI大模型
开发语言·人工智能·python
不像程序员的程序媛8 小时前
Nginx日志切分
服务器·前端·nginx
Yvonne爱编码8 小时前
JAVA数据结构 DAY6-栈和队列
java·开发语言·数据结构·python
Re.不晚8 小时前
JAVA进阶之路——无奖问答挑战1
java·开发语言
Daniel李华8 小时前
echarts使用案例
android·javascript·echarts
北原_春希8 小时前
如何在Vue3项目中引入并使用Echarts图表
前端·javascript·echarts