这是我参与2022首次更文挑战的第6天,活动详情查看:2022首次更文挑战
我们在前面的文章介绍了Promise的相关知识,及它的一些方法。下面我们就来实现一个自己的Promise,我们知道Promise()是一个构造函数,可以创建一个新的Promise对象。所以在这里我使用ES6的方式来定义一个类MyPromise.
executor
executor对应的就是MyPromise类中的构造函数,在构造函数中,需要立即执行excutor()
// 类
class MyPromise {
// constructor:构造函数 executor:执行器
constructor (executor) {
executor(resolve, reject)
}
}
module.exports = MyPromise;
为MyPromise定义状态
const PENDING = 'PENDING', FULFILLED = 'FULFILLED', REJECTED = 'REJECTED';
Promise中初始化的状态为pending状态,只能由pending转为其他状态(resolve或者reject),而且不能在转回去。
// 每个promise,都有自己的执行器 —— 有自己的resolve,reject。ES6中,如果在外面定义方法,实际上是定义在prototype上面了
/**
* @description 定义函数resolve:更改状态
*/
const resolve = (value) => {
if (this.status === PENDING) {
this.status = FULFILLED;
this.value = value;
}
}
/**
* @description 定义函数reject:更改状态
*/
const reject = (reason) => {
if (this.status === PENDING) {
this.status = REJECTED;
this.reason = reason;
}
}
实现then方法
then方法中有成功的回调(onFulfilled)和失败的回调(onRejected)两个参数。
promise.then(onFulfilled, onRejected)
then(onFulfilled, onRejected) {
// onFulfilled执行条件
if (this.status === FULFILLED) {
onFulfilled(this.value);
}
// onRejected执行条件
if (this.status === REJECTED) {
onRejected(this.reason);
}
}
注意:捕获异常,如果有异常,直接执行rejected
// 捕获异常,如果有异常,直接执行rejected
try {
executor(resolve, reject);
} catch (error) {
reject(error);
}
最基本版的promise实现
代码如下:
MyPromise类:
调用自己的Promise:
简单版promise基本实现,但还有很多问题,比如:
- 遇到异步问题如何解决?
- promise.then的链式调用如何实现?
这里接着做一些扩展。之前简单版promise还存在着一些问题,比如在promise中出现了异步的程序如何解决?
处理Promise中的异步与多次调用的问题
异步程序是说excutor执行器在执行之后的状态并没有改变,所以在then的时候并不知道走那个状态。 需要在then中处理pending这个状态的。并且then方法要按照调用的原有顺序去执行,依次去执行成功的回调或者是失败的回调。
- 在pending状态的时候去收集成功的回调或者是失败的回调
- 在构造函数中定义
onFulfilledCallbacks收集成功的回调,定义onRejectedCallbacks收集失败的回调——这里要用到发布订阅模式