持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第16天,点击查看活动详情
题外话
这个疫情啊,真滴是服气了,居家快一个月了,居家不是办公就是做饭,脑子都快麻木了,为了活跃自己的大脑,也为了帮助大家增长知识,我给大家分享一点冷知识,嘿嘿嘿……
冷知识:你晕不晕车,跟你吃没吃饭,没有一点关系,唯一的区别就是:
你吃饭了,吐的是食物;
你没吃饭,吐的是胆汁。
所以下回谁再拿我晕车阻止我吃饭你看着,哼哼
前情回顾
前两篇手撕Promise
系列,对then方法进行了简单的处理:接收返回值、异步调用、多次调用进行了处理,关于then的处理其实还有很多,那就接着往下处理
链式调用
promise是可以进行链式调用的,then方法的链式调用后一个返回值实际上接收的是上一个then方法的返回值
1.then方法返回的是一个promise对象才能进行链式调用。
2.new Promise一旦新建就会立即执行
3.then方法需要接收上一个then方法的返回值作为传入的参数
- then方法想要链式调用就需要返回的是一个promise对象
- 需要对上一个then方法的返回值进行保存,将保存的返回值重新重新调用。
- 对返回的值进行处理,如果是普通值就直接调用
resolve
,将这个值传递给下一个promise
对象;如果是一个promise
对象,我们就需要判断这个promise
对象的返回值,调用不同的回调函数进行处理。
因为对返回值进行处理,成功、失败和异步处理都需要进行一遍,所以我们可以抽离出去
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
class MyPromise {
constructor(executor) {
executor(this.resolve, this.reject)
}
status = PENDING
resp = undefined
error = undefined
// successCallBack = undefined
// failCallback = undefined
successCallBack = []
failCallback = []
resolve = (resp) => {
if (this.status !== PENDING) return
this.status = FULFILLED
this.resp = resp
// this.successCallBack && this.successCallBack(this.resp)
while (this.successCallBack.length) this.successCallBack.shift()(this.resp)
}
reject = (error) => {
if (this.status !== PENDING) return
this.status = REJECTED
this.error = error
// this.failCallback && this.failCallback(this.error)
while (this.failCallback.length) this.failCallback.shift()(this.error)
}
then(successCallBack, failCallback) {
//1.1 then方法需要返回一个promise对象
let promise = new MyPromise((resolve, reject) => {
//1.2 回到函数是同步代码,而new MyPromise调用就会执行,所以将判断代码移入
if (this.status === FULFILLED) {
//2.1 将上一个then方法的返回值保存起来
let successResult = successCallBack(this.resp)
//2.2 将保存的返回值执行resolve再次返回返回值调用,在3.6中废除
//resolve(successResult)
//3.6 通过调用抽离的类型判断进行重新处理
returnPromise(successResult, resolve, reject)
} else if (this.status == REJECTED) {
failCallback(this.error)
} else {
// this.successCallBack = successCallBack
// this.failCallback = failCallback
this.successCallBack.push(successCallBack)
this.failCallback.push(failCallback)
}
})
return promise
}
}
//3.1 抽离一个公共的方法对promise返回值的类型进行判断处理
// result就是上一个then方法的返回值,也是需要进行判断处理的值
function returnPromise(result, resolve, reject) {
//3.2 判断返回的result是否是MyPromise的实例,就相当于判断result是否是promise对象
if (result instanceof MyPromise) {
//3.4 如果是promise对象,那么就需要通过then方法判断这个result这个返回值的状态,并且调用resolve或者reject,将返回值传递给下一个promise对象
// result.then(resp => resolve(resp), error => reject(error))
//3.5 可以进行简写
result.then(resolve, rejct)
} else {
//3.3 如果是普通类型,直接调用resolve方法,将返回值传递给下一个promise对象
resolve(result)
}
}
这里我们可以进行依次验证
- 验证基础链式调用
let promise = new MyPromise((resolve, reject) => {
resolve(1)
})
promise.then(resp => {
console.log(resp);
return 100
}).then(resp => {
console.log(resp);
})
这段代码的输出结果是1 100。说明promise的第一个then方法将100成功返回出去了,第二个then方法成功接收了上一个then方法的返回值。
- 验证链式调用返回值类型不同
let promise = new MyPromise((resolve, reject) => {
resolve(1)
})
function other() {
return new MyPromise((resolve,rejct) => {
resolve('other')
})
}
promise.then(resp => {
console.log(resp);
return other()
}).then(resp => {
console.log(resp);
})
这段代码的输出结果是1 other,说明我们对于promise对象作为返回值的处理也成功了。
结束
这一张主要介绍的就是关于then方法链式调用相关的一些处理