自己的Promise

废话不多说,直接上代码:

class myPromise {
  constructor(fn) {
    this.status = 'pending';
    this.resolveCbs = [];
    this.rejectCbs = [];
    this.value = null;
    fn(this._resolve.bind(this), this._reject.bind(this));
    return this;
  }
  _resolve(val) {
    if (this.status === 'pending') {
      this.value = val;
      this.status = 'fulfilled';
      this.resolveCbs.forEach(cb => {
        cb(this.value);
      })
    }
  }
  _reject(err) {
    if (this.status === 'pending') {
      this.value = err;
      this.status = 'rejected';
      this.rejectCbs.forEach(cb => {
        cb(this.value);
      })
      // 如果没有处理函数,则直接抛错
      if (this.rejectCbs.length === 0) {
        throw err
      }
    }
  }
  then(resolveCb, rejectCb) {
    if (this.status !== 'pending') {
      const cb = this.status === 'fulfilled' ? resolveCb : rejectCb;
      const self = new myPromise((resolve, reject) => {
        this._handleCb(cb, this.value, resolve, reject, self);
      })
      return self;
    } else {
      const self = new myPromise((resolve, reject) => {
        if (typeof resolveCb === 'function') {
          this.resolveCbs.push(res => {
            this._handleCb(resolveCb, res, resolve, reject, self);
          })
        }
        if (typeof rejectCb === 'function') {
          this.rejectCbs.push(res => {
            this._handleCb(rejectCb, res, resolve, reject, self);
          })
        }
      })
      return self;
    }
  }
  catch(rejectCb) {
    return this.then(null, rejectCb)
  }
  _handleCb(cb, res, resolve, reject, self) {
    try {
      const ret = cb(res)
      if (ret instanceof Promise || ret instanceof myPromise) {
        if (ret === self) {
          throw new Error('检测到myPromise链式循环')
        }
        ret.then(res => resolve(res))
      } else {
        resolve(ret)
      }
    } catch (err) {
      reject(err)
    }
  }
}
new myPromise((resolve, reject) => {
  setTimeout(() => {
    resolve(456)
  }, 1000);
}).then(res => {
  console.log(res)
  throw 'hualala'
}).catch(err => {
  console.log('heng!!!')
  return new myPromise((resolve, reject) => {
    setTimeout(() => {
      reject(233)
    }, 1000);
  })
}).then(res => {
  console.log(res)
})

这个简版的Promise已经可以实现到链式的地步了, 如果return是一个非Promise,则直接resolve,如果是Promise,则等then再resolve

 
原文地址:https://www.cnblogs.com/amiezhang/p/8006370.html