「这是我参与11月更文挑战的第5天,活动详情查看:2021最后一次更文挑战」。
传送门
从零手撕Promise,掌握Promise的实现原理(1)之promise基本结构的实现 从零手撕Promise,掌握Promise的实现原理(2)之基础版本的promise实现 从零手撕Promise,掌握Promise的实现原理(3)之回调地狱是什么 从零手撕Promise,掌握Promise的实现原理(4)之then方法链式调用的初步实现
回顾
经过上次的介绍我们的then方法已经有一个初步的样子了,我们的promise变成了这样:
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
class Promise{
constructor(executor){
this.state = PENDING
this.value = undefined
this.reason = undefined
//存放onFulfilled
this.onResolvedCallbacks = []
//存放onRejected
this.onRejectedCallbacks = []
const resolve = (value) => {
if (this.state === PENDING) {
this.value = value
this.state = FULFILLED
//promise实例状态改变后调用暂存的onFulfilled
this.onResolvedCallbacks.forEach(fn => fn())
}
}
const reject = (reason) => {
if (this.state === PENDING) {
this.reason = reason
this.state = REJECTED
//promise实例状态改变后调用的onRejected
this.onRejectedCallbacks.forEach(fn => fn())
}
}
try {
//executor函数执行过程中出错,将会导致Promise失败
executor(resolve,reject)
} catch (error) {
reject(error)
}
}
then(onFulfilled, onRejected){
let promise = new Promise((resolve, reject) => {
switch(this.state){
case FULFILLED:
try{
let x = onFulfilled(this.value)
resolve(x)
} catch(e){
reject(e)
}
break
case REJECTED:
try{
let x = onRejected(this.reason)
resolve(x)
} catch(e){
reject(e)
}
break
default:
this.onResolvedCallbacks.push(() => {
try{
let x = onFulfilled(this.value)
resolve(x)
} catch(e){
reject(e)
}
})
this.onRejectedCallbacks.push(() => {
try{
let x = onRejected(this.reason)
resolve(x)
} catch(e){
reject(e)
}
})
}
})
return promise
}
}
then方法返回的是Promise
- 如果调用
Promise实例的then方法返回的是一个Promise,那么我们需要判断这个Promise的状态.- 如果
Promise是成功的,就将成功的结果,传递到then方法返回的Peomise的成功回调当中; - 如果
Promise是失败的,就将失败的原因,传递到then方法返回的Peomise的失败回调当中。
- 如果
- 那么我们的
then方法,就不能简单的直接将其回调的返回值,传递到这个then方法要返回的Promise中了. - 这里我们通过一个方法来解析
then方法回调的返回值,我们称这个方法为resolvePromise, 这个方法不是Promise这个类上的方法. - 对于resolvePromise,这个方法的作用就是解析
then方法中回调函数的返回值,根据返回值是什么,来改变then方法中将要返回的Promise的状态. - 因此我们需要四个参数分别是,
then方法要返回的Promise、then方法中回调函数的返回值x、将要返回的promise的resolve函数与reject函数。 - 相应的then方法也要进行改造。
const resolvePromise = (promise, x, resolve, reject) => {
}
then(onFulfilled, onRejected){
let promise = new Promise((resolve, reject) => {
switch(this.state){
case FULFILLED:
try{
let x = onFulfilled(this.value)
//这里就不能简单的resolve(x)了,而要通过resolvePromise去解析返回值
resolvePromise(promise, x, resolve, reject)
} catch(e){
reject(e)
}
break
case REJECTED:
try{
let x = onRejected(this.reason)
resolvePromise(promise, x, resolve, reject)
} catch(e){
reject(e)
}
break
default:
this.onResolvedCallbacks.push(() => {
try{
let x = onFulfilled(this.value)
resolvePromise(promise, x, resolve, reject)
} catch(e){
reject(e)
}
})
this.onRejectedCallbacks.push(() => {
try{
let x = onRejected(this.reason)
resolvePromise(promise, x, resolve, reject)
} catch(e){
reject(e)
}
})
}
})
return promise
}
到此我们的完整的Promise,长这样
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
const resolvePromise = (promise, x, resolve, reject) => {
}
class Promise{
constructor(executor){
this.state = PENDING
this.value = undefined
this.reason = undefined
//存放onFulfilled
this.onResolvedCallbacks = []
//存放onRejected
this.onRejectedCallbacks = []
const resolve = (value) => {
if (this.state === PENDING) {
this.value = value
this.state = FULFILLED
//promise实例状态改变后调用暂存的onFulfilled
this.onResolvedCallbacks.forEach(fn => fn())
}
}
const reject = (reason) => {
if (this.state === PENDING) {
this.reason = reason
this.state = REJECTED
//promise实例状态改变后调用的onRejected
this.onRejectedCallbacks.forEach(fn => fn())
}
}
try {
//executor函数执行过程中出错,将会导致Promise失败
executor(resolve,reject)
} catch (error) {
reject(error)
}
}
then(onFulfilled, onRejected){
let promise = new Promise((resolve, reject) => {
switch(this.state){
case FULFILLED:
try{
let x = onFulfilled(this.value)
resolvePromise(promise, x, resolve, reject)
} catch(e){
reject(e)
}
break
case REJECTED:
try{
let x = onRejected(this.reason)
resolvePromise(promise, x, resolve, reject)
} catch(e){
reject(e)
}
break
default:
this.onResolvedCallbacks.push(() => {
try{
let x = onFulfilled(this.value)
resolvePromise(promise, x, resolve, reject)
} catch(e){
reject(e)
}
})
this.onRejectedCallbacks.push(() => {
try{
let x = onRejected(this.reason)
resolvePromise(promise, x, resolve, reject)
} catch(e){
reject(e)
}
})
}
})
return promise
}
}
为什么then方法中的回调(onFulfilled、onRejected)是微任务?
思考下面图片中的问题
resolvePromise的实现留给下一篇文章
传送门
从零手撕Promise,掌握Promise的实现原理(1)之promise基本结构的实现 从零手撕Promise,掌握Promise的实现原理(2)之基础版本的promise实现 从零手撕Promise,掌握Promise的实现原理(3)之回调地狱是什么 从零手撕Promise,掌握Promise的实现原理(4)之then方法链式调用的初步实现