「这是我参与11月更文挑战的第4天,活动详情查看:2021最后一次更文挑战」。
建议阅读前几篇文章
从零手撕Promise,掌握Promise的实现原理(1)之promise基本结构的实现 从零手撕Promise,掌握Promise的实现原理(2)之基础版本的promise实现 从零手撕Promise,掌握Promise的实现原理(3)之回调地狱是什么
回顾
我们已经完成了基出版本的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){
if (this.state === FULFILLED) {
onFulfilled(this.value)
}
if (this.state === REJECTED) {
onRejected(this.reason)
}
if (this.state === PENDING) {
//如果此时promise实例的状态还未确定,我们需要将onFulfilled与onRejected存起来,等到promise实例状态改变后再去调用
this.onResolvedCallbacks.push(() => {
onFulfilled(this.value)
})
this.onRejectedCallbacks.push(() => {
onRejected(this.reason)
})
}
}
}
Promise的then链调用机制
- 通过上一篇回调地狱的介绍我们可以发现,
promise的then链机制,可以让我们用同步代码的编写方式,去编写我们的异步代码,promise的then链机制也是promise实现的最核心的地方,接下来我们将根据Peomise A+来继续实现我们的Peomise
then方法返回普通值
-
promise实例的then方法有两个参数,一个是成功后执行的回调(onFulfilled)一个是失败后执行的回调(onRejected),如果then的回调(成功的回调或者失败的回调)返回一个普通值(不是Promise,也不是抛出错误),则会将结果传递到下一次then的成功回调中。
-
- 因为
then方法是链式调用的,因此then方法每次返回的都是一个Promise实例。
- 因为
-
- 在执行
onFulfilled与onRejected的时候如果执行过程出现异常,那么会把这个异常抛出到下一次then的失败回调中去。
- 在执行
- 代码实现如下:
then(onFulfilled, onRejected){
let promise = new Promise((resolve, reject) => {
switch(this.state){
case FULFILLED:
//执行回调的过程中,出现异常,那么会把这个异常抛出到下一次`then`的失败回调中去。
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)
}
})
}
})
//返回一个 Promise
return promise
}
-
至此我们已经完成了
then方法的初步版本,我们可以初步测试一下let Promise = require('./promise/1.promise.js') let p = new Promise((resolve,reject) => { resolve('成功') }) p.then(value => { console.log('value',value); return 10000000000000 },reason => { console.log('reason',reason); }).then(value => { console.log('value',value); },reason => { console.log('reason',reason); }) -
从打印结果可以看出我们的
then方法已经满足返回普通值的链式调用了传送门
从零手撕Promise,掌握Promise的实现原理(1)之promise基本结构的实现
从零手撕Promise,掌握Promise的实现原理(2)之基础版本的promise实现 从零手撕Promise,掌握Promise的实现原理(3)之回调地狱是什么