手写一个MyPromise构造函数
参考网上资料,自己整理了一下思路
首先是一个最简化的MyPromise构造函数,参数是executor执行器函数。
接下来是,给这个构造函数增加then方法和catch方法。
打印结果是
最后一步是使构造函数可以链式调用。
function MyPromise(excutor) { console.log('进入MyPromise构造器'); const _PENDING = 'pending'; const _RESOLVED = 'resolved'; const _REJECTED = 'rejected'; const self = this; // 定义一个this指向, 避免在当前作用域下的this混乱 self.PromiseStatus = _PENDING; self.PromiseValue = undefined; self.fullFilledList = []; // 用来存储Promise.then成功的回调函数 self.rejectedList = []; // 用来存储Promise.then和Promise.catch失败的回调函数 // success const resolve = data => { console.log('用户调用resolve方法,状态被推向resolved状态,并且将用户传递进来的数据赋值给PromiseValue'); if (self.PromiseStatus === _PENDING) { self.PromiseStatus = _RESOLVED; self.PromiseValue = data; self.fullFilledList.forEach(item => { console.log('一旦用户状态被推向resolved状态则调用fullFilledList里面存储的成功的回调函数'); item(); }); } } // error const reject = error => { console.log('用户调用reject方法,状态被推向rejected状态,并且将用户传递进来的数据赋值给PromiseValue'); if (self.PromiseStatus === _PENDING) { self.PromiseStatus = _REJECTED; self.PromiseValue = error; self.rejectedList.forEach(item => { console.log('一旦用户状态被推向rejected状态则调用rejectedList里面存储的失败的回调函数'); item(); }); } } try { console.log('到达立即执行器'); excutor(resolve,reject); } catch(error) { reject(error); } MyPromise.prototype.then = (thenable, catchable) => { console.log('进入then函数'); // 如果当前状态已经为已决阶段的两种状态了, 那么回调函数会被立即调用并执行 // 因为catchable很有可能不传递, 所以必须容错 catchable = typeof catchable === 'function' ? catchable : err => { throw err }; if (self.PromiseStatus === _RESOLVED) { // console.log('MyPromise实例是resolved状态, 调用成功回调函数thenable-then,并返回PromiseValue'); // thenable(self.PromiseValue) console.log('MyPromise实例是resolved状态,为了链式调用需要return出一个新的MyPromise实例'); return new MyPromise((resolve, reject) => { try { const x = thenable(self.PromiseValue); // thenable回调函数return出的内容 if (x instanceof MyPromise) { x.then(resolve, reject) // ??? 以后补充 } else { resolve(x) // 将初始的pending状态推向resolved状态 } } catch (err) { reject(err) } }) } if (self.PromiseStatus === _REJECTED) { // console.log('MyPromise实例是rejected状态, 调用失败回调函数catchable-then,并返回PromiseValue'); // catchable(self.PromiseValue) console.log('MyPromise实例是rejected状态,为了链式调用需要return出一个新的MyPromise实例'); return new MyPromise((resolve, reject) => { try { console.log('调用失败回调函数catchable-then,并返回PromiseValue'); const x = catchable(self.PromiseValue) if (x instanceof MyPromise) { x.then(resolve, reject) } else { resolve(x) } } catch (err) { reject(err) } }) } if (self.PromiseStatus === _PENDING) { console.log('MyPromise实例是pending状态'); return new MyPromise((resolve, reject) => { self.fullFilledList.push(() => { const x = thenable(self.PromiseValue) if (x instanceof MyPromise) { x.then(resolve, reject) } else { resolve(x) } }) self.rejectedList.push(() => { try { const x = catchable(self.PromiseValue) if (x instanceof Promise) { x.then(resolve, reject) } else { resolve(x) } } catch (err) { reject(err) } }) }) } } MyPromise.prototype.catch = catchable => { console.log('进入catch函数'); // if (self.PromiseStatus === _REJECTED) { // console.log('MyPromise实例是rejected状态, 调用失败回调函数catchable-catch'); // catchable(self.PromiseValue) // } return self.then(null, catchable); } }; const myPromise = new MyPromise((resolve, reject) => { // 立即执行且顺序执行 console.log('我会立即执行'); reject('hello'); }) const myPromise1 = myPromise.then(res => { console.log(res, 'thenable执行-then'); }, err => { console.log(err, 'catchable执行-then'); return err; }) myPromise1.then(res => { console.log(res, '第二个then'); return res + ' world'; }).then(res => { console.log(res, '第三个then'); }) // const myPromise2 = myPromise.catch(err => { // console.log(err, 'catchable执行-catch'); // })
后续再完善。