Es6 Promise 实现

// promise 状态
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';

const isFn = fn => typeof fn === 'function';

class Promise {
  constructor(resolver) {
    if (!isFn(resolver)) {
      throw new TypeError('Promise 参数必须是函数');
    }

    //状态和值
    this._status = PENDING;
    this._value;

    //执行队列
    this._fulfilledQueue = [];
    this._rejectedQueue = [];

    //绑定this
    this._resolve = this._resolve.bind(this);
    this._reject = this._reject.bind(this);

    resolver(this._resolve, this._reject);
  }

  _resolve(val) {
    if (this._status !== PENDING) return;
    //因为Promise里面的函数是同步的,then是异步的
    setTimeout(() => {
      this._status = FULFILLED;
      this._value = val;
      let cb;
      while (cb = this._fulfilledQueue.shift()) {
        cb(this._value)
      }
    }, 0);
  }

  _reject(val) {
    if (this._status !== PENDING) return;
    //因为Promise里面的函数是同步的,then是异步的
    setTimeout(() => {
      this._status = REJECTED;
      this._value = val;
      let cb;
      while (cb = this._rejectedQueue.shift()) {
        cb(this._value)
      }
    }, 0);
  }

  // then 参数类型:
  //(1)值 
  //(2)函数, 返回值或者Promise
  then(onFulfilled, onRejected) {
    return new Promise((resolve, reject) => {
      // 返回一个 resolve 或者 reject 函数
      let runThen = (callback, resolver) => {
        return function (val) {
          try {
            if (!isFn(callback)) { // 判断 onFulfilled、onRejected 是否是一个 function,否的话直接透传value
              resolver(val)
            } else {
              const res = callback(val); // 判断函数返回值是否是一个 Promise
              if (res instanceof Promise) {
                res.then(resolve, reject);
              } else {
                resolver(res)
              }
            }
          } catch (err) {
            reject(err);
          }
        }
      }
      //判断当前的status
      switch (this._status) {
        case FULFILLED:
            runThen(onFulfilled, resolve)(this._value);
          break;
        case REJECTED:
            runThen(onRejected, reject)(this._value);
          break;
        case PENDING: //状态未变,将函数添加到执行队列,等待状态改变后执行
          this._fulfilledQueue.push(runThen(onFulfilled, resolve));
          this._rejectedQueue.push(runThen(onRejected, reject));
          break;
      }
    });
  }

  static resolve(promise) {
    // 判断 promise 是否是一个 promise 对象
    if (promise instanceof Promise) {
      return promise;
    } else {
      return new Promise(resolve => {
        resolve(promise);
      });
    }
  }

  static reject(err){
    return new Promise((resolve, reject) => reject(err));
  }

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

  finally(callback) {
    return this.then(
      value => Promise.resolve(callback()).then(() => value),
      reason => Promise.resolve(callback()).then(() => { throw reason })
    );
  }

  static race(pmList) {
    return new Promise((resolve, reject) => {
      pmList.forEach(item => {
        // item 可能不是 promise,所以先调用 promise.resolve
        Promise.resolve(item).then(val => {
          resolve(val);
        }, err => {
          reject(err);
        });
      })
    })
  }

  static all(pmList) {
    return new Promise((resolve, reject) => {
      let resolveArr = [];
      let count = 0;
      pmList.forEach((item, index) => {
        // item 可能不是 promise,所以先调用 promise.resolve
        Promise.resolve(item).then(val => {
          resolveArr[index] = val;
          count++;
          if (count === pmList.length) {
            resolve(resolveArr);
          }
        }, err => {
          reject(err);
        });
      })
    })
  }
}

你可能感兴趣的:(Es6 Promise 实现)