promise 的实现原理
- pending
- fulfilled
- rejected
class Promise { constructor(executor) { // Promise接一个办法 (resolve,reject)=>{} // 开始的状态 this.state = 'pending' // 胜利的状态 this.value = undefined // 失败的状态 this.result = undefined // 状态执行的时候,要立刻扭转,且不可逆转 const resolve = (value) => { if (this.state === 'pending') { this.state = 'fulfilled' this.value = value } } const reject = (reason) => { if (this.state === 'pending') { this.state = 'rejected' this.result = reason } } executor(resolve, reject) //这个办法要立刻执行 } // then承受两个参数,都是办法 then(onFulfilled, onRejected) { // 如果这样写是同步的,this.state始终是padding的状态 console.log(this.state) // 如果胜利,传入胜利的参数 if (this.state === 'fulfilled') { onFulfilled(this.value) } // 如果失败,传入失败的参数 if (this.state === 'rejected') { onRejected(this.result) } }}
- 下面是同步的,执行then办法后,this.state始终是pending的状态
公布订阅者模式
module.exports = class Promise { constructor(executor) { // Promise接一个办法 (resolve,reject)=>{} // 开始的状态 this.state = 'pending' // 胜利的状态 this.value = undefined // 失败的状态 this.result = undefined // 胜利的订阅者数组 this.onResolvedCallbacks = [] // 失败的订阅者数组 this.onRejectedCallbacks = [] // 状态执行的时候,要立刻扭转,且不可逆转 const resolve = (value) => { if (this.state === 'pending') { this.state = 'fulfilled' this.value = value // 执行resolve的时候,把 this.onResolvedCallbacks外面的办法全副执行一遍 this.onResolvedCallbacks.forEach(fn => fn()) } } const reject = (reason) => { if (this.state === 'pending') { this.state = 'rejected' this.result = reason // 执行reject的时候,把 this.onRejectedCallbacks外面的办法全副执行一遍 this.onRejectedCallbacks.forEach(fn => fn()) } } executor(resolve, reject) //这个办法要立刻执行 } // then承受两个参数,都是办法 then(onFulfilled, onRejected) { // 如果这样写是同步的,this.state始终是padding的状态 // 如果胜利,传入胜利的参数 if (this.state === 'fulfilled') { onFulfilled(this.value) } // 如果失败,传入失败的参数 if (this.state === 'rejected') { onRejected(this.result) } // 公布订阅者模式 // 如果状态是 pending // 就把要做的办法传入 待发布状态中去 if (this.state === 'padding') { this.onResolvedCallbacks.push(() => { onFulfilled(this.value) }) this.onRejectedCallbacks.push(() => { onRejected(this.result) }) } }}
- 然而下面没有链式调用。then()办法前面不能接then()
解决then()办法不返回promise的问题
class Promise { constructor(executor) { // Promise接一个办法 (resolve,reject)=>{} // 开始的状态 this.state = 'pending' // 胜利的状态 this.value = undefined // 失败的状态 this.result = undefined // 胜利的订阅者数组 this.onResolvedCallbacks = [] // 失败的订阅者数组 this.onRejectedCallbacks = [] // 状态执行的时候,要立刻扭转,且不可逆转 const resolve = (value) => { if (this.state === 'pending') { this.state = 'fulfilled' this.value = value // 执行resolve的时候,把 this.onResolvedCallbacks外面的办法全副执行一遍 this.onResolvedCallbacks.forEach(fn => fn()) } } const reject = (reason) => { if (this.state === 'pending') { this.state = 'rejected' this.result = reason // 执行reject的时候,把 this.onRejectedCallbacks外面的办法全副执行一遍 this.onRejectedCallbacks.forEach(fn => fn()) } } executor(resolve, reject) //这个办法要立刻执行 } // then承受两个参数,都是办法 then(onFulfilled, onRejected) { // 如果这样写是同步的,this.state始终是padding的状态 // 如果胜利,传入胜利的参数 const promise2 = new Promise((resolve, reject) => { // 解决不能链式调用的问题。须要再返回一个promise if (this.state === 'fulfilled') { setTimeout(() => { const x = onFulfilled(this.value) resolvePromise(promise2, x, resolve, reject) }, 0) } // 如果失败,传入失败的参数 if (this.state === 'rejected') { setTimeout(() => { const x = onRejected(this.result) resolvePromise(promise2, x, resolve, reject) }, 0) } // 公布订阅者模式 // 如果状态是 padding // 就把要做的办法传入 待发布状态中去 if (this.state === 'padding') { this.onResolvedCallbacks.push(() => { setTimeout(() => { const x = onFulfilled(this.value) resolvePromise(promise2, x, resolve, reject) }, 0) }) this.onRejectedCallbacks.push(() => { setTimeout(() => { const x = onRejected(this.result) resolvePromise(promise2, x, resolve, reject) }, 0) }) } }) return promise2 }}// 定义resolvePromise 办法const resolvePromise = (promise2, x, resolve, reject) => { // console.log(promise2, x, resolve, reject) if (promise2 === x) { console.log(11111) return reject(new TypeError('循环援用!')) } // 判断 x 的类型 if (typeof x === 'function' || (typeof x === 'object' && x !== null)) { // 简单类型 try { const then = x.then if (typeof then === 'function') { // 认为这个的确是一个promise then.call(x, y => { // 只能解决一次,如果resolve外面嵌套n个promise // resolve(y) // 递归解析以后的x resolvePromise(promise2, y, resolve, reject) }, r => { reject(r) }) } } catch (error) { reject(error) } } else { // 根本类型 resolve(x) }}