Their Promise

Ado, directly on the code:

class myPromise {
  constructor(fn) {
    this.status = 'pending';
    this.resolveCbs = [];
    this.rejectCbs = [];
    this.value = null;
    fn(this._resolve.bind(this), this._reject.bind(this))
  }
  _resolve(val) {
    this.value = val;
    this.status = 'resolved';
    this.resolveCbs.forEach(cb => {
      cb(this.value);
    })
  }
  _reject(err) {
    this.value = err;
    this.status = 'rejected';
    this.rejectCbs.forEach(cb => {
      cb(this.value);
    })
  }
  then(resolveCb, rejectCb) {
    if (this.status === 'resolved') {
      resolveCb(this.value);
    } else if (this.status === 'rejected') {
      rejectCb(this.value);
    } else {
      return new myPromise((resolve, reject) => {
        if (typeof resolveCb === 'function') {
          this.resolveCbs.push(res => {
            this._handleCb(resolveCb, res, resolve, reject);
          })
        }
        if (typeof rejectCb === 'function') {
          this.rejectCbs.push(res => {
            this._handleCb(rejectCb, res, resolve, reject);
          })
        }
      })
    }
  }
  catch(rejectCb) {
    return this.then(null, rejectCb)
  }
  _handleCb(cb, res, resolve, reject) {
    try {
      const ret = cb(res)
      if (ret instanceof Promise || ret instanceof 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 => {
    setTimeout(() => {
      resolve(233)
    }, 1000);
  })
}).then(res => {
  console.log(res)
})

 

The simple version of Promise can already be achieved to the point where the chain, if return is a non-Promise, directly resolve, if a Promise, and so then again the resolve

Guess you like

Origin www.cnblogs.com/amiezhang/p/8006370.html