肝了一天,研究大佬们的手写Promise, 终究是我太菜。(仅供自己参考,勿进。只有代码实现,没有思路)

从早上肝到晚上,结果promise链式调用还没研究出来,我tm好菜啊!!!

all

方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。

参数必须是具有 Iterator 接口,且返回的每个成员都是 Promise 实例。

该方法如果传入的promise实例都被resolve后才会将状态改变为fulfilled,只要有一个实例被reject后,他就被rejected,然后返回第一个被reject的实例。

race

方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。

如果传入的promise实例,有一个状态改变,那么promise.race的状态也随之改变,这个就好像赛跑一样,那一个promise的实例的状态先改变,promise.race的实例也随之改变。

该方法的作用是控制网络加载时长,如果到时见还没有加载完毕,就将他的状态变为rejected

const p = Promise.race([
  fetch('/resource-that-may-take-a-while'),
  new Promise(function (resolve, reject) {
    setTimeout(() => reject(new Error('request timeout')), 5000)
  })
]);
​
p
.then(console.log)
.catch(console.error);
复制代码

allSettled

用来确定一组异步操作是否都结束了(不管成功或失败)。

一旦发生状态变更,状态总是fulfilled,不会变成rejected

then方法接收的参数与promise实例传入的顺序相对应。是promise的实例改变状态传入的参数。

  • 成功时: {status:‘fulfilled’, value:成功时传入的参数}
  • 失败时: {status:‘rejected’, reason: 失败时传入的参数}

any

方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。

该方法与all方法对应。

只要参数实例有一个变成fulfilled状态,包装实例就会变成fulfilled状态;如果所有参数实例都变成rejected状态,包装实例就会变成rejected状态。

手写代码

    /**
     * promise接收一个executor函数。该函数接收两个参数
     * 
     * all:如果传入的promise状态都变成了fulfilled,那么将返回resolve参数的数组
     * 如果传入的promise有一个状态变成了rejected,那么将返回reason参数。
     * 
     * race: 传入的promises,谁先改变状态,这race的状态就随之改变。
     * 
     * allSettled: 传入的promises,如果状态都改变,不管是fulfilled或者是      rejected,都会直接改变promise的状态。
     * */
    class MyPromise {
      constructor(executor) {
        let resolve = (value) => {
          // 这里一定要做一下判断,只有当状态处于pending的时候才能改变状态,将状态改变为fulfilled
          if (this.status === 'pending') {
            this.status = 'fulfilled'
            this.value = value
            // 当resolve异步执行时,我们将执行事件数组中的函数
            this.fulfilledArr.forEach(fn => {
              fn && fn()
            });
          }
        }
        let reject = (reason) => {
          // 这里一定要做一下判断,只有当状态处于pending的时候才能改变状态,将状态改变为rejected
          if (this.status === 'pending') {
            this.status = 'rejected'

            this.reason = reason
            // console.log("当前reason的值", this.reason, reason)
            // 当rejected异步执行时,我们将执行事件数组中的函数
            this.rejectedArr.forEach(fn => {
              fn && fn()
            });
          }
        }
        // 定义一个状态变量
        this.status = 'pending';
        // 定义一个fulfilled状态下传递的参数
        this.value = null;
        // 定义一个rejected状态下传递的参数
        this.reason = null;
        // 成功的事件数组
        this.fulfilledArr = []
        this.rejectedArr = []
        try {
          executor(resolve, reject)
        } catch (error) {
          reject(error)
        }
      }

      // static all(promises) {
      //   let successArr = [];
      //   for (let i = 0; i < promises.length; i++) {
      //     if (promises[i].status === 'rejected') {
      //       return new MyPromise((resolve, reject) => {
      //         // console.log("=======调用了", promises[i].reason, i)
      //         reject(promises[i].reason)
      //       })
      //     }

      //     if (promises[i].status === 'fulfilled') {
      //       console.log("=======调用了", promises[i].value, i)
      //       successArr.push(promises[i].then(res => {
      //         successArr.push(res)
      //       }))
      //     }
      //   }
      //   if (successArr.length === promises.length) {
      //     return new MyPromise((resolve, reject) => {
      //       try {
      //         resolve(successArr)
      //       } catch (error) {
      //         reject(error)
      //       }
      //     })
      //   }

      // }

      static all(promises) {
        let arr = [];
        let count = 0;
        return new MyPromise((resolve, reject) => {
          for (let i = 0; i < promises.length; i++) {
            promises[i].then(data => {
              arr[i] = data;
              count++;
              // 如果状态全部为fulfilled,那么将返回异步传入的参数,数组形式。
              if (count == promises.length) {
                resolve(arr);
              };
              // 如果一个promise出现错误,那么它将传递参数到reject函数。这个reject是内部自己实现的函数。
            }, (err) => {
              reject(err)
            });
          };
        });
      }

      // race方法

      static race(promises) {
        return new MyPromise((resolve, reject) => {
          for (let i = 0; i < promises.length; i++) {
            // 由于循环是瞬间执行的
            promises[i].then(resolve, reject)
          }
        })
      }

      // any 方法,实现方式刚好和all方法相反
      static any(promises) {
        let rejectArr = [];

        return new MyPromise((resolve, reject) => {
          for (let i = 0; i < promises.length; i++) {
            promises[i].then((res) => {
              resolve(res)
            }, (err) => {
              rejectArr.push(err);
              if (promises.length === rejectArr.length) {
                reject(rejectArr)
              }
            })
          }
        })
      }

      // allSettled方法
      static allSettled(promises) {
        let arr = []
        return new Promise((resolve, reject) => {
          // 只要状态全部改变,他就会改变。
          for (let i = 0; i < promises.length; i++) {
            promises[i].then(res => {
              arr.push({
                status: 'fulfilled',
                value: res
              })
              // fulfilled都需要判断是否执行完毕
              if (arr.length === promises.length) {
                resolve(arr)
              }
            }, (err) => {
              arr.push({
                status: 'rejected',
                reason: err
              })
              // fulfilled都需要判断是否执行完毕
              if (arr.length === promises.length) {
                resolve(arr)
              }
            })

          }
        })
      }
      
      // resolve方法
      static resolve(params) {
        return new MyPromise((resolve) => {
          resolve(params)
        })
      }

      // reject方法
      static reject(params) {
        return new MyPromise((resolve, reject) => {
          reject(params)
        })
      }
      
      // catch方法
      catch(onFail) {
        return this.then(null, onFail)
      }

      // 定义then方法
      then(onSuccess, onFail) {
        let x;
        return new Promise((resolve, reject) => {
          // 确定状态,然后让对应的状态函数执行。
          if (this.status === 'fulfilled') {
            try {
              // 穿透,当没有提供then中的回调函数,会将resolve, reject的参数向下传递
              onSuccess = typeof onSuccess === 'function' ? onSuccess : v => v;
              x = onSuccess(this.value)
              resolve(x)
            } catch (err) {
              reject(err)
            }
          }
          if (this.status === 'rejected') {
            try {
              // 穿透,当没有提供then中的回调函数,会将resolve, reject的参数向下传递
              onFail = typeof onFail === 'function' ? onFail : v => v;
              x = onFail(this.reason)
              resolve(x)
            } catch (err) {
              reject(err)
            }
          }
          // 当状态为pending时,将事件放入对应的事件数组中
          if (this.status === 'pending') {
            // this.fulfilledArr.push(
            //   onSuccess)
            // this.rejectedArr.push(
            //   onFail)
            this.fulfilledArr.push(() => {
              try {
                // 穿透,当没有提供then中的回调函数,会将resolve, reject的参数向下传递
                onSuccess = typeof onSuccess === 'function' ? onSuccess : v => v;
                x = onSuccess(this.value)
                resolve(x)
              } catch (err) {
                reject(err)
              }
            })
            this.rejectedArr.push(() => {
              try {
                // 穿透,当没有提供then中的回调函数,会将resolve, reject的参数向下传递
                onFail = typeof onFail === 'function' ? onFail : v => v;
                x = onFail(this.reason)
                resolve(x)
              } catch (err) {
                reject(err)
              }
            })
          }
        })
      }
    }
复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享