持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第17天,点击查看活动详情
题外话
这个疫情啊,真滴是服气了,居家快一个月了,居家不是办公就是做饭,脑子都快麻木了,为了活跃自己的大脑,也为了帮助大家增长知识,我给大家分享一点冷知识,嘿嘿嘿……
冷知识:你晕不晕车,跟你吃没吃饭,没有一点关系,唯一的区别就是:
你吃饭了,吐的是食物;
你没吃饭,吐的是胆汁。
所以下回谁再拿我晕车阻止我吃饭你看着,哼哼
前情回顾
promise里面最复杂就是then方法的实现,在promise系列里面我们首先完成了
这些是我们在前三篇中已经完成的部分,那么还有什么是我们目前还没有实现的呢
正文
我们先看一个例子
let promise = new Promise((resolve, reject) => {
resolve(1)
})
let p1 = promise.then(resp => {
console.log(resp);
return p1
})
此时会抛出一个错误TypeError: Chaining cycle detected for promise #<Promise>
我们也需要加工一下我们自己封装的MyPromise
解决promise循环调用问题
我们可以判断返回的promise和返回值result是否相等,如果相等就说明返回了自己,就需要执行reject将失败的结果抛出。
- 对判断类型的函数新接收一个参数,是返回的promise对象,用来和返回值result进行对比
- 我们会发现在new Promise我们是获取不到promise对象的,因为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 = []
failCallback = []
resolve = (resp) => {
if (this.status !== PENDING) return
this.status = FULFILLED
this.resp = resp
while (this.successCallback.length) this.successCallback.shift()(this.resp)
}
reject = (error) => {
if (this.status !== PENDING) return
this.status = REJECTED
this.error = error
while (this.failCallback.length) this.failCallback.shift()(this.error)
}
then(successCallback, failCallback) {
let promise = new MyPromise((resolve, reject) => {
if (this.status === FULFILLED) {
//3. 因为new Promise是立即执行的,在Promise执行过程中获取不到执行结果promise,所以使用异步处理在Promise执行之后,获取执行结果promise
setTimeout(() => {
let result = successCallback(this.resp)
//2. 将promise传入
returnPromise(promise, result, resolve, reject)
}, 0)
} else if (this.status === REJECTED) {
failCallback(this.error)
} else {
this.successCallback.push(successCallback)
this.failCallback.push(failCallback)
}
})
return promise
}
}
function returnPromise(promise, result, resolve, reject) {
//1. 对判断类型的函数新增一个参数promise,对promise和result返回值进行判断,如果promise和result相等,说明返回是自己本身,使用reject抛出错误
if (promise === result) {
return reject('TypeError: Chaining cycle detected for promise #<Promise>')
}
if (result instanceof MyPromise) {
result.then(resolve, reject)
} else {
resolve(result)
}
}
结束
到目前为止我们对then方法来说解决了基础搭建,接收返回值,多次调用,链式调用,循环调用的问题,那么如果我们在立即执行new Promise这个执行器里面代码执行出现问题呢?then方法回调函数类型代码出现问题呢?失败reject回调函数链式调用?then方法的参数是不是可选参数?
这些我们将在后面的博客里面进行详细讲解~~~~