实现Promise的resolve/reject/then/all/race/finally/catch方法

promise实现基本思路和基本原理:
1.Promise三种状态Pending-等待 Fulfilled-成功 Rejected-失败
2.Promise中的状态使用resolve和reject 2个函数改变状态 并且是不可逆
3.executer如果有错误代码 那么Promise的状态会修改为rejected状态
4.Promise传入一个参数executer执行器,有两个参数分别是resolve和reject函数
5.then方法传入两个参数,分别是onFulfilled和onReject两个函数,当Promise内部状态改变时,调用相关状态回调函数
6.多次调用then方法思路:
(1) 多次调用then方法,应该把onFulfilled和onReject方法缓存
(2) 当Promise状态改变时,去触发相应状态缓存的方法
(3) 发布订阅模式
7.then实现链式调用
(1) 链式调用返回一个Promise
(2) then如果返回是一个普通值,那么作为下一个then的结果
(3) then抛出异常 那么作为下一个then的失败结果
(4) then返回是一个Promise 需要等待这个Promise执行完
8.catch的实现,其实就是将then方法中的第二个参数onReject实现报错调用
9.finally的实现,无论是成功还是失败都会调用执行
10.Promise.all 原理:当传入的数组每一个promise调用结果状态都是成功,那么返回一个数组包含入参返回值
11.Promise.race 原理:当传入的数组每一个promise调用,返回值由最快改变状态的Promise决定

代码实现

1.定义Promise三种状态和调用executer函数执行,定义status、value 、callbacks 等类成员变量,处理有可能报错

class MyPromise {
	 static PENDING = 'pending';
	  static FULFILLED = 'fulfilled';
	  static REJECTED = 'rejected';
	  
	 constructor(executer) {
	    //初始状态
	    this.status = MyPromise.PENDING;
	    //初始值
	    this.value = null;
	    //等待状态成功和失败函数暂时存放起来
	    this.callbacks = [];
	
	    //传入的函数 resolve 和 reject参数
	    try {
	      executer(this.resolve.bind(this), this.reject.bind(this));
	    } catch (error) {
	      this.reject.bind(this, error);
	    }
	  }

}

2.实现类resolve和reject方法

 resolve(val) {
    //只有pending状态才会改变
    if (this.status === MyPromise.PENDING) {
      this.status = MyPromise.FULFILLED;
      this.value = val;

      //多次触发then和异步处理方案
      setTimeout(() => {
        this.callbacks.map((callback) => {
          callback.onFulfilled(val);
        });
      });
    }
  }

  reject(reason) {
    //只有pending状态才会改变
    if (this.status === MyPromise.PENDING) {
      this.status = MyPromise.REJECTED;
      this.value = reason;

      //多次触发then和异步处理方案
      setTimeout(() => {
        this.callbacks.map((callback) => {
          callback.onReject(reason);
        });
      });
    }
  }

3.实现类then的方法和链式调用

then(
    onFulfilled = (val) => val,
    onReject = (reason) => {
      throw reason;
    }
  ) {
    const promise = new MyPromise((resolve, reject) => {
      switch (this.status) {
        //等待状态
        case MyPromise.PENDING:
          this.callbacks.push({
            onFulfilled: (val) => {
              try {
                const res = onFulfilled(val);
                this.resolvePromise(promise, res, resolve, reject);
              } catch (error) {
                reject(error);
              }
            },
            onReject: (reason) => {
              try {
                const res = onReject(reason);
                this.resolvePromise(promise, res, resolve, reject);
              } catch (error) {
                reject(error);
              }
            },
          });
          break;

        //成功状态
        case MyPromise.FULFILLED:
          //异步执行 替代微任务
          setTimeout(() => {
            try {
              const res = onFulfilled(this.value);
              this.resolvePromise(promise, res, resolve, reject);
            } catch (error) {
              reject(error);
            }
          });

          break;
        //失败状态
        case MyPromise.REJECTED:
          //异步执行 替代微任务
          setTimeout(() => {
            try {
              const resErr = onReject(this.value);
              //这里注意 上一步的是reject状态 下一个链式then接收结果是resolve接收
              resolve(resErr);
            } catch (error) {
              reject(error);
            }
          });
          break;
      }
    });
    //返回一个promise实例
    return promise;
  }

4.实现类catch的方法

 catch(onReject) {
    return this.then(undefined, onReject);
  }

5.实现类finally的方法

  //成功和失败都会执行
  finally(callback) {
    return this.then(
      (val) => {
        return MyPromise.resolve(callback()).then(() => val);
      },
      (reason) => {
        return MyPromise.resolve(callback()).then(() => reason);
      }
    );
  }

6.实现类then核心代码复用逻辑resolvePromise

//then核心代码复用逻辑
  resolvePromise(p, res, resolve, reject) {
    //不能重复传入同一个Promise
    if (p === res) throw new TypeError('Chaining cycle detected');

    try {
      // 返回结果是一个promise对象 那么直接调用then
      if (res instanceof MyPromise) {
        res.then(
          (val) => resolve(val),
          (reason) => reject(reason)
        );
      } else {
        resolve(res);
      }
    } catch (error) {
      reject(error);
    }
  }

7.实现静态方法resolve

//静态resolve 返回一个promise 执行resolve方法
  static resolve(val) {
    return new MyPromise((resolve, reject) => {
      if (val instanceof MyPromise) {
        val.then(resolve, reject);
      } else {
        resolve(val);
      }
    });
  }

8.实现静态方法reject

//静态resolve 返回一个promise 执行reject方法
  static reject(reason) {
    return new MyPromise((resolve, reject) => {
      reject(reason);
    });
  }

9.静态all方法 数组所有promise都请求成功才返回resolve 有一个失败就直接reject返回

static all(promiseArr) {
    const values = [];

    return new MyPromise((resolve, reject) => {
      promiseArr.map((promise) => {
        promise.then(
          (val) => {
            values.push(val);

            if (values.length === promiseArr.length) {
              resolve(values);
            }
          },
          (reason) => reject(reason)
        );
      });
    });
  }

10.静态race方法 不管是resolve还是reject谁先调用就执行谁 只会执行第一个成功的

 static race(promiseArr) {
    return new MyPromise((resolve, reject) => {
      promiseArr.map((promise) => {
        promise.then(
          (val) => resolve(val),
          (reason) => reject(reason)
        );
      });
    });
  }

结尾附上完整版代码,为了测试不和原生的Promise名字冲突,此处名字用MyPromise。

class MyPromise {
  static PENDING = 'pending';
  static FULFILLED = 'fulfilled';
  static REJECTED = 'rejected';

  constructor(executer) {
    //初始状态
    this.status = MyPromise.PENDING;
    //初始值
    this.value = null;
    //等待状态成功和失败函数暂时存放起来
    this.callbacks = [];

    //传入的函数 resolve 和 reject参数
    try {
      executer(this.resolve.bind(this), this.reject.bind(this));
    } catch (error) {
      this.reject.bind(this, error);
    }
  }

  resolve(val) {
    //只有pending状态才会改变
    if (this.status === MyPromise.PENDING) {
      this.status = MyPromise.FULFILLED;
      this.value = val;

      //多次触发then和异步处理方案
      setTimeout(() => {
        this.callbacks.map((callback) => {
          callback.onFulfilled(val);
        });
      });
    }
  }

  reject(reason) {
    //只有pending状态才会改变
    if (this.status === MyPromise.PENDING) {
      this.status = MyPromise.REJECTED;
      this.value = reason;

      //多次触发then和异步处理方案
      setTimeout(() => {
        this.callbacks.map((callback) => {
          callback.onReject(reason);
        });
      });
    }
  }

  then(
    onFulfilled = (val) => val,
    onReject = (reason) => {
      throw reason;
    }
  ) {
    const promise = new MyPromise((resolve, reject) => {
      switch (this.status) {
        //等待状态
        case MyPromise.PENDING:
          this.callbacks.push({
            onFulfilled: (val) => {
              try {
                const res = onFulfilled(val);
                this.resolvePromise(promise, res, resolve, reject);
              } catch (error) {
                reject(error);
              }
            },
            onReject: (reason) => {
              try {
                const res = onReject(reason);
                this.resolvePromise(promise, res, resolve, reject);
              } catch (error) {
                reject(error);
              }
            },
          });
          break;

        //成功状态
        case MyPromise.FULFILLED:
          //异步执行 替代微任务
          setTimeout(() => {
            try {
              const res = onFulfilled(this.value);
              this.resolvePromise(promise, res, resolve, reject);
            } catch (error) {
              reject(error);
            }
          });

          break;
        //失败状态
        case MyPromise.REJECTED:
          //异步执行 替代微任务
          setTimeout(() => {
            try {
              const resErr = onReject(this.value);
              //这里注意 上一步的是reject状态 下一个链式then接收结果是resolve接收
              resolve(resErr);
            } catch (error) {
              reject(error);
            }
          });
          break;
      }
    });
    //返回一个promise实例
    return promise;
  }

  //返回失败的结果
  catch(onReject) {
    return this.then(undefined, onReject);
  }

  //成功和失败都会执行
  finally(callback) {
    return this.then(
      (val) => {
        return MyPromise.resolve(callback()).then(() => val);
      },
      (reason) => {
        return MyPromise.resolve(callback()).then(() => reason);
      }
    );
  }

  //then核心代码复用逻辑
  resolvePromise(p, res, resolve, reject) {
    //不能重复传入同一个Promise
    if (p === res) throw new TypeError('Chaining cycle detected');

    try {
      // 返回结果是一个promise对象 那么直接调用then
      if (res instanceof MyPromise) {
        res.then(
          (val) => resolve(val),
          (reason) => reject(reason)
        );
      } else {
        resolve(res);
      }
    } catch (error) {
      reject(error);
    }
  }

  //静态resolve 返回一个promise 执行resolve方法
  static resolve(val) {
    return new MyPromise((resolve, reject) => {
      if (val instanceof MyPromise) {
        val.then(resolve, reject);
      } else {
        resolve(val);
      }
    });
  }

  //静态resolve 返回一个promise 执行reject方法
  static reject(reason) {
    return new MyPromise((resolve, reject) => {
      reject(reason);
    });
  }

  /* 
    Promise.all和Promise.race的实现原理:
    Promise.all 原理:当传入的数组每一个promise调用结果状态都是成功,那么返回一个数组包含入参返回值
    Promise.race 原理:当传入的数组每一个promise调用,返回值由最快改变状态的Promise决定
  */
  //静态all方法 数组所有promise都请求成功才返回resolve 有一个失败就直接reject返回
  static all(promiseArr) {
    const values = [];

    return new MyPromise((resolve, reject) => {
      promiseArr.map((promise) => {
        promise.then(
          (val) => {
            values.push(val);

            if (values.length === promiseArr.length) {
              resolve(values);
            }
          },
          (reason) => reject(reason)
        );
      });
    });
  }
  //静态race方法 不管是resolve还是reject谁先调用就执行谁 只会执行第一个成功的
  static race(promiseArr) {
    return new MyPromise((resolve, reject) => {
      promiseArr.map((promise) => {
        promise.then(
          (val) => resolve(val),
          (reason) => reject(reason)
        );
      });
    });
  }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

追逐梦想之路_随笔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值