众所周知,promise虽然本质上也是回调,但是解决了令人眼花撩乱的地狱回调问题,也可以链式调用,同时也对等待多个异步网络请求后处理问题很友好,那现在咱们来手写一个简单的promise呗。
promise 只有三种状态,pending,fullfilled和rejected,默认是pending状态,通过调用resolve方法将状态变为fullfilled,调用reject方法或者同步代码块抛出异常时,将状态变为rejected,并且一旦是fullfilled或者rejected状态,就不能再改变状态了。
const PENDING = 'PENDING'const FULLFILLED = 'FULLFILLED'const REJECTED = 'REJECTED'class MyPromise { constructor(excutor) { this.status = PENDING this.value = undefined // 成功参数 this.reason = undefined // 失败原因 // 发布订阅模式, 订阅回调函数,excutor有异步宏任务时 this.fullfilledList = [] // 成功回调 this.rejectedList = [] // 失败回调 this.resolve = (val) => { if (this.status === PENDING) { this.status = FULLFILLED this.value = val // 发布成功回调 this.fullfilledList.forEach(cb => cb()) } } this.reject = (val) => { if (this.status === PENDING) { this.status = REJECTED this.reason = val // 发布失败回调 this.rejectedList.forEach(cb => cb()) } } try { excutor(this.resolve, this.reject) } catch (e) { this.reject(e) } } then(onFullfilled, onRejected) { if (this.status === FULLFILLED) { onFullfilled(this.value) } if (this.status === REJECTED) { onRejected(this.reason) } if (this.status === PENDING) { this.fullfilledList.push(() => { onFullfilled(this.value) }) this.rejectedList.push(() => { onRejected(this.reason) }) } // 链式模式 return this }}new MyPromise((resolve, reject) => { setTimeout(() => { reject('failed') // 会被执行 }, 0)}).then(resolve => { console.log(resolve)}, reject => { console.log(reject)}).then(resolve => { console.log(resolve)}, reject => { console.log(reject)})new MyPromise((resolve, reject) => { setTimeout(() => { reject('failed') // 不会被执行 }, 0) process.nextTick(() => { resolve('success') })}).then(resolve => { console.log(resolve)}, reject => { console.log(reject)}).then(resolve => { console.log(resolve)}, reject => { console.log(reject)})