自己的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