这是我参与「第四届青训营 」笔记创作活动的第14天
前言
最近学习了Promise,当然实现手写promise也是必不可少的一步。 下面是我学习到的一些内容,还有一些api和小部分功能没有完善。下面是我的代码思路已经过程。
手写思路
1. 变量声明以及resolve和reject
解释
定义了三个状态,PromiseResult,PromiseStatus。
this.resolve = this.resolve.bind(this)
通过bind将this锁在 resolve 函数中,防止在其他环境调用该函数时this指向不正确,相当于在MyPromise中定义了一个 self = this 并在函数中使用 self.promiseResult = value ...
2.解决只能有一个 resolve或reject被执行
很简单加上一个判断就可以实现。如果未执行的话 PromiseStatus的状态是 pending ,如果执行后就会改变,通过这点来进行判断。
3.实现在promise中抛出异常
executor 这里是执行器同步调用两个函数的地方,在这里可以捕获到错误并进行处理。promise中抛出异常代表执行reject,异常中的信息会被传到参数中。
4.实现基础.then
.then接收两个参数,resolve时的回调函数和reject时的回调函数,这两个内容必须时函数,并会将 resolve('参数值')传给对应的回调函数。同时这个参数值时 promiseResult 的内容, reject同理.
这里的onFulfilled和onRejected就是接受的回调函数。
5.解决异步promise导致状态不变
如果只是上面这种写法,当promise中的内容是异步时
状态不会第一时间发生改变,但是
.then却会被立即执行。就导致 状态是 pending不能匹配。但这时不知道异步运行的结果,不可以随便判断写 resolve 或者 reject。
这是最好的方法就是先把回调函数存起来,当结果确定时,再调用相应的函数。
if (this.PromiseState === 'fulfilled') {
// 如果当前为成功状态,执行第一个回调
onFulfilled(this.promiseResult)
} else if (this.PromiseState === 'rejected') {
// 如果当前为失败状态,执行第二个回调
onRejected(this.promiseResult)
} else if (this.PromiseState === 'pending') {
// 如果状态为待定状态,暂时保存两个回调
// 如果状态为待定状态,暂时保存两个回调
this.onFulfilledCallbacks.push(onFulfilled(this.promiseResult))
this.onRejectedCallbacks.push(onRejected(this.promiseResult))
}
6.解决then的返回
现在的代码结构是这样的
但我们都知道promise.then的返回值依旧是一个promise对象,同时这个promise的结果也是不定的
- 当回调函数返回的是promise对象,那么这个.then的返回值和这个promise的结果相同
- 当回调返回不是promise对象,那么.then的返回值是成功的promise,且promiseResult是返回值。
- 当回调抛出错误,那么.then的结果是 失败的promise,值为throw的内容。
了解到上面的内容我们首先要确定,要返回一个promise对象
接下来就要判断回调函数的类型,看是不是promise类型的返回值。
这里的思路是 创建一个
resolvePromise传递回调函数,并在内部 通过callbackResult获取回调函数的返回值。并进行判断操作。
后面还有几个API后续补充