promise 的实现原理
- 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)
}
}
发表回复