# promise

手写源码

class Mypromise {
  constructor(fn) {
    // 表示状态
    this.state = "pending";
    // 表示then注册的成功函数
    this.successFun = [];
    // 表示then注册的失败函数
    this.failFun = [];

    let resolve = val => {
      // 保持状态改变不可变(resolve和reject只准触发一种)
      if (this.state !== "pending") return;

      // 成功触发时机  改变状态 同时执行在then注册的回调事件
      this.state = "success";
      // 为了保证then事件先注册(主要是考虑在promise里面写同步代码) promise规范 这里为模拟异步
      setTimeout(() => {
        // 执行当前事件里面所有的注册函数
        this.successFun.forEach(item => item.call(this, val));
      });
    };

    let reject = err => {
      if (this.state !== "pending") return;
      // 失败触发时机  改变状态 同时执行在then注册的回调事件
      this.state = "fail";
      // 为了保证then事件先注册(主要是考虑在promise里面写同步代码) promise规范 这里模拟异步
      setTimeout(() => {
        this.failFun.forEach(item => item.call(this, err));
      });
    };
    // 调用函数
    try {
      fn(resolve, reject);
    } catch (error) {
      reject(error);
    }
  }

  // 实例方法 then
  then(resolveCallback, rejectCallback) {
    // 判断回调是否是函数
    resolveCallback =
      typeof resolveCallback !== "function" ? v => v : resolveCallback;
    rejectCallback =
      typeof rejectCallback !== "function"
        ? err => {
            throw err;
          }
        : rejectCallback;
    // 为了保持链式调用  继续返回promise
    return new Mypromise((resolve, reject) => {
      // 将回调注册到successFun事件集合里面去
      this.successFun.push(val => {
        try {
          //    执行回调函数
          let x = resolveCallback(val);
          //(最难的一点)
          // 如果回调函数结果是普通值 那么就resolve出去给下一个then链式调用  如果是一个promise对象(代表又是一个异步) 那么调用x的then方法 将resolve和reject传进去 等到x内部的异步 执行完毕的时候(状态完成)就会自动执行传入的resolve 这样就控制了链式调用的顺序
          x instanceof Mypromise ? x.then(resolve, reject) : resolve(x);
        } catch (error) {
          reject(error);
        }
      });

      this.failFun.push(val => {
        try {
          //    执行回调函数
          let x = rejectCallback(val);
          x instanceof Mypromise ? x.then(resolve, reject) : reject(x);
        } catch (error) {
          reject(error);
        }
      });
    });
  }
  
  // 静态方法
  static all(promiseArr) {
    let result = [];
    return new Mypromise((resolve, reject) => {
      for (let i = 0; i < promiseArr.length; i++) {
        promiseArr[i].then(
          res => {
            result.push(res);
            //只有全部的promise执行成功之后才resolve出去
            if (result.length === promiseArr.length) {
              resolve(result);
            }
          },
          err => {
            reject(err);
          }
        );
      }
    });
  }
  
  // 静态方法
  static race(promiseArr) {
    return new Mypromise((resolve, reject) => {
      for (let i = 0; i < promiseArr.length; i++) {
        promiseArr[i].then(
          res => {
          //promise数组只要有任何一个promise 状态变更  就可以返回
            resolve(res);
          },
          err => {
            reject(err);
          }
        );
      }
    });
  }
}

// 使用
let promise1 = new Mypromise((resolve, reject) => {
  setTimeout(() => {
    resolve(123);
  }, 2000);
});
let promise2 = new Mypromise((resolve, reject) => {
  setTimeout(() => {
    resolve(1234);
  }, 1000);
});

// Mypromise.all([promise1,promise2]).then(res=>{
//   console.log(res);
// })

// Mypromise.race([promise1, promise2]).then(res => {
//   console.log(res);
// });

promise1
  .then(
    res => {
      console.log(res); //过两秒输出123
      return new Mypromise((resolve, reject) => {
        setTimeout(() => {
          resolve("success");
        }, 1000);
      });
    },
    err => {
      console.log(err);
    }
  )
  .then(
    res => {
      console.log(res); //再过一秒输出success
    },
    err => {
      console.log(err);
    }
  );
Last Updated: 7/16/2020, 4:28:33 PM