promise

205 阅读1分钟
class Promise {
  callbacks = [];
  name = '';
  state = 'pending';//增加状态
  value = null;//保存结果
  constructor(fn) {
    this.name = `Promse-${promiseCount++}`;
    console.log('[%s]:constructor', this.name);
    fn(this._resolve.bind(this), this._reject.bind(this));
  }
  then(onFulfilled, onRejected) {
    console.log('[%s]:then', this.name);
    return new Promise((resolve, reject) => {
      this._handle({
        onFulfilled: onFulfilled || null,
        onRejected: onRejected || null,
        resolve: resolve,
        reject: reject
      });
    });
  }
  static resolve(value) {
    if (value && value instanceof Promise) {
      return value;
    } else if (value && typeof value === 'object' && typeof value.then === 'function') {
      let then = value.then;
      return new Promise(resolve => {
        then(resolve);
      });

    } else if (value) {
      return new Promise(resolve => resolve(value));
    } else {
      return new Promise(resolve => resolve());
    }
  }
  static reject(value) {
    if (value && typeof value === 'object' && typeof value.then === 'function') {
      let then = value.then;
      return new Promise((resolve, reject) => {
        then(reject);
      });
    } else {
      return new Promise((resolve, reject) => reject(value));
    }
  }
  static all(promises) {
    const l = promises.length 
    let i = 0
    const resArr = new Array(promises.length)
    return new Promise((resolve, reject) => {
      promises.forEach((v, j) => {
        Promise.resolve(v).then((res, rej) => {
          i++
          resArr[j] = res
          if (l === i) resolve(resArr)
        }, err => reject(err))
      })
    })
  }
  static race(promises) {
    return new Promise((resolve, reject) => {
     
      promises.forEach((promise, index) => {
        Promise.resolve(promise).then(result => {
          resolve(result);
        }, reason => reject(reason));
      })

    })
  }
  _handle(callback) {
    console.log('[%s]:_handle', this.name, 'state=', this.state);

    if (this.state === 'pending') {
      this.callbacks.push(callback);
      console.log('[%s]:_handle', this.name, 'callbacks=', this.callbacks);
      return;
    }

    let cb = this.state === 'fulfilled' ? callback.onFulfilled : callback.onRejected;

    if (!cb) {//如果then中没有传递任何东西
      cb = this.state === 'fulfilled' ? callback.resolve : callback.reject;
      cb(this.value);
      return;
    }
    let ret
    try {
        ret = cb(this.value);
        cb = this.state === 'fulfilled' ? callback.resolve : callback.reject;
    } catch (error) {
        ret = error;
        cb = callback.reject
    } finally {
        cb(ret);
    }

  }
  _resolve(value) {
    if (this.state !== 'pending') {
      throw new Error('Promise state is single! ')
      return
    }
    console.log('[%s]:_resolve', this.name);
    console.log('[%s]:_resolve', this.name, 'value=', value);

    if (value && (typeof value === 'object' || typeof value === 'function')) {
      var then = value.then;
      if (typeof then === 'function') {
        then.call(value, this._resolve.bind(this), this._reject.bind(this));
        return;
      }
    }

    this.state = 'fulfilled';//改变状态
    this.value = value;//保存结果
    this.callbacks.forEach(callback => this._handle(callback));
  }
  _reject(error) {

    if (this.state !== 'pending') {
      throw new Error('Promise state is single! ')
      return
    }
    console.log('[%s]:_reject', this.name);
    console.log('[%s]:_reject', this.name, 'value=', error);

    this.state = 'rejected';
    this.value = error;
    this.callbacks.forEach(callback => this._handle(callback));
  }
}