Promise简单实现

177 阅读2分钟

promise实现

  1. 定义类,声明状态和值,声明一个执行者executor,resolve或rejected方法在executor中调用

  2. then方法的实现(包含then接受的两个函数,以及pending的实现)

  3. 链式的实现

  4. 返回类型(promise or 普通值)

  5. Promise.resolve/race/all/reject实现

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

    constructor(executor) {
      this.status = PR.PENDING; // 初始化状态为pending
      this.value = null; // 值
      // 4. 处理promise为pending时的状态
      this.callbacks = [];

      try {
        // executor执行者
        executor(this.resolve.bind(this), this.reject.bind(this))
      } catch (e) {
        this.reject(e)
      }
    }

    // Promise.resolve实现
    static resolve(value) {
      return new PR((resolve, reject) => {
        if (value instanceof PR) {
          value.then(resolve, reject);
        } else {
          resolve(value);
        }
      });
    }

    // Promise.reject实现
    static reject(reason) {
      return new PR((_, reject) => {
        reject(reason);
      });
    }


    // Promise.race实现
    static race(promises) {
      return new PR((resolve, reject) => {
        promises.map(promise => {
          promise.then(value => {
            resolve(value);
          });
        });
      });
    }

    // Promise.all实现
    static all(promises) {
      let resolves = [];
      return new PR((resolve, reject) => {
        promises.forEach((promise, index) => {
          promise.then(
            value => {
              resolves.push(value);
              if (resolves.length == promises.length) {
                resolve(resolves);
              }
            },
            e => {
              reject(e);
            }
          );
        });
      });
    }

    resolve(value) {
      if (this.status === PR.PENDING) {
        this.status = PR.FULFILLED; // 状态置为完成
        this.value = value;
        // 4.2 resovle中添加处理callback方法并且定义为异步任务
        setTimeout(() => {
          this.callbacks.map(callback => {
            callback.onFulfilled(value)
          })
        })
      }
    }

    reject(value) {
      if (this.status === PR.PENDING) {
        this.status = PR.REJECTED; // 状态置为失败
        this.value = value;
        // 4.3 reject中添加处理callback方法并定义为异步任务
        setTimeout(() => {
          this.callbacks.map(callback => {
            callback.onRejected(value)
          })
        })
      }
    }

    // 2. then方法来处理状态的改变
    then(onFulfilled, onRejected) { // then接收两个参数,即成功和失败的回调函数
      // 因为两个函数参数不是必填的,所以需要多做一步操作,设置默认值为函数
      if (typeof onFulfilled != 'function') {
        onFulfilled = value => value;
      }

      if (typeof onRejected != 'function') {
        onRejected = value => value
      }

      // 5. 链式调用
      let promise = new PR((resolve, reject) => {
        // 4.1 pending的处理
        if(this.status == PR.PENDING) {
          let obj = {
            onFulfilled: value => {
              try {
                let result = onFulfilled(value)
                // 6. 返回类型,实现不同类型不同处理机制
                this.parse(promise, result, resolve, reject);
              } catch (e) {
                onRejected(e)
              }
            },
            onRejected: value => {
              try {
                let result = onRejected(value)
                this.parse(promise, result, resolve, reject);
              } catch (e) {
                onRejected(e)
              }
            }
          }
          this.callbacks.push(obj)
        }
        
        // 成功
        if (this.status == PR.FULFILLED) {
          // 3. 使用setTimeout来将onFulfilled与onRejected做为异步宏任务执行
          setTimeout(() => {
            try {
              let result = onFulfilled(this.value)
              this.parse(promise,result, resolve, reject);
            } catch (e) {
              onRejected(e);
            }
          });
        }
        
        // 失败
        if (this.status == PR.REJECTED) {
          setTimeout(() => {
            try {
              let result = onRejected(this.value)
              this.parse(promise, result, resolve, reject);
            } catch (e) {
              onRejected(e);
            }
          });
        }
      })
      return promise;
    }
    
    // 代码复用
    parse(promise, result, resolve, reject) {
      if (promise == result) {
        throw new TypeError("Chaining cycle detected for promise");
      }
      try {
        if(result instanceof PR) {
          result.then(resolve, reject);
        } else {
          resolve(result);
        }
      } catch (e) {
        reject(e);
      }
    }
  }
  
  
  // 举例
  PR.resolve("resolve").then(value => {
    console.log(value);
  });

  let p = new PR((resolve, reject) => {
    resolve(1)
  }).then(value => {
    console.log(value);
    return new PR((resolve, reject) => {
      resolve('返回promise')
    })
  }).then(value => {
    console.log(value)
  })

备注: 参考自后盾人大叔(绝绝子)