手动实现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
});
相关推荐
熊猫钓鱼>_>2 分钟前
Kotlin Multiplatform for OpenHarmony 实战:kotlinx-coroutines 结构化并发适配
开发语言·kotlin·agent·harmonyos·openharmony·适配·华为云码道
结局无敌3 分钟前
React Native for OpenHarmony 实战:三方库 react-native-progress-steps 的鸿蒙化适配指南
javascript·人工智能·深度学习·react native·react.js·harmonyos
涛涛ing9 分钟前
Chrome DevTools MCP 正式可用:AI 终于能自己开浏览器调试你的页面了
前端
tryCbest11 分钟前
第三篇:JavaScript 基础语法全解 + TaskFlow 逻辑实现
javascript·前端知识
沫璃染墨15 分钟前
《Qt从零入门系列(十四):QThread多线程详解——从线程创建到客户端阻塞处理》
开发语言·c++·笔记·qt·ui·交互·线程
after you20 分钟前
【无标题】
前端·javascript
酷炫码神21 分钟前
Day 6|ES6+ 语法:把现代 JS 写顺手,从解构到 map / filter / reduce
前端·javascript·es6
hixiong12328 分钟前
C# 使用 ZXingCpp.Angle 进行条码、二维码识别
开发语言·c#·扫码
云和数据.ChenGuang29 分钟前
AI 工程师相关就业岗位(细分,偏工程落地,由底层到上层)
服务器·开发语言·人工智能·python
lemon_sjdk33 分钟前
从一段真实的 Electron IM 前端代码,看高级前端的工程化修养
前端·electron·状态模式·im