要深入理解Promise就自己实现一下Promise吧!不了解Promise的移步 👉🏻 Promise 入门
Promise实现
分析一下Promie的的实现
Promise 是一个类,会传入一个Function,并立即执行
Promise有三个状态:
- pending 进行中
- fulfilled 成功
- rejected 失败
状态只能由 Pending --> Fulfilled 或者 Pending --> Rejected,且一但发生改变便不可二次修改
Promise中使用resolve和rejected改变状态
then方法判断Promise状态
初始化一个Promise类
class MyPromise {
PENDING = 'pending';
FULFILLED = 'fulfilled';
REJECTED = 'rejected';
status; // 状态
value = null; // 成功的返回的value
reason = null; // 失败原因
constructor(executor) {
// 初始化状态
this.status = this.PENDING;
// 这是Promise接收的函数,立即执行
executor(this._resolve,this._reject) // 传入Promise成功和失败的回调
}
// 失败的回调
_reject(reason){
// 修改状态为失败
if (this.status === this.PENDING) {
// 修改状态和reason值
this.status = this.REJECTED;
this.reason = reason;
}
}
// 成功的回调
_resolve(value){
// 修改状态为成功
if (this.status === this.PENDING) {
// 修改状态和reason值
this.status = this.FULFILLED;
this.value = value;
}
}
}
现在就可以通过调用reject和resolve来改变MyPromise的状态了
再看看then的实现
then是用来判断状态的,接受两个函数
then(onFulfilled, onRejected){
if (this.status === this.FULFILLED) {
onFulfilled(this.value) // 调用成功的回调,返回value
}
if (this.status === this.REJECTED) {
onRejected(this.reason) // 调用失败的回调,返回失败原因
}
}
执行一下,发现并没有console
这里涉及到了js循环机制EventLoop ,then执行的时候resolve并没有执行,status还是pending状态;但是resolve执行的时候then已经执行过了,不会再执行了
这里再添加两个存储数组来存放成功和失败的回调 onFulfilledCallbacks、onRejectedCallbacks
class MyPromise {
PENDING = 'pending';
FULFILLED = 'fulfilled';
REJECTED = 'rejected';
status; // 状态
value = null; // 成功的返回的value
reason = null; // 失败原因
onFulfilledCallbacks = [];
onRejectedCallbacks = [];
constructor(executor) {
// 初始化状态
this.status = this.PENDING;
// 这是Promise接收的函数,立即执行
executor(this._resolve.bind(this),this._reject.bind(this)) // 传入Promise成功和失败的回调
}
// 失败的回调
_reject(reason){
// 修改状态为失败
if (this.status === this.PENDING) {
// 修改状态和reason值
this.status = this.REJECTED;
this.reason = reason;
while(this.onRejectedCallbacks.length) {
// 执行失败队列中的回调
this.onRejectedCallbacks.shift()(reason);
}
}
}
// 成功的回调
_resolve(value){
// 修改状态为成功
if (this.status === this.PENDING) {
// 修改状态和reason值
this.status = this.FULFILLED;
this.value = value;
while(this.onFulfilledCallbacks.length) {
// 执行成功队列中的回调
this.onFulfilledCallbacks.shift()(value);
}
}
}
then(onFulfilled, onRejected){
const onFulfilledCallback = () => {
onFulfilled(this.value) // 调用成功的回调,返回value
};
const onRejectedCallback = () => {
onRejected(this.reason) // 调用失败的回调,返回失败原因
};
// 状态为成功时
if (this.status === this.FULFILLED) {
onFulfilledCallback();
}
// 状态为失败时
if (this.status === this.REJECTED) {
onRejectedCallback();
}
// 状态为进行中
if(this.status === this.PENDING) {
// 把成功和失败的回调存到对应的队列
this.onFulfilledCallbacks.push(onFulfilledCallback);
this.onRejectedCallbacks.push(onRejectedCallback);
}
}
}
执行成功
then的链式调用
我们的then并没有返回结果,没法继续执行then方法
那就给then返回一个 新的Promise
then(onFulfilled, onRejected){
const _this = this;
return new MyPromise((resolve, reject) => {
const onFulfilledCallback = () => {
this.isPromise(onFulfilled(_this.value), resolve, reject); // 调用成功的回调,返回value
};
const onRejectedCallback = () => {
this.isPromise(onRejected(_this.reason), resolve, reject); // 调用失败的回调,返回失败原因
};
// 状态为成功时
if (_this.status === _this.FULFILLED) {
onFulfilledCallback();
}
// 状态为失败时
if (_this.status === _this.REJECTED) {
onRejectedCallback();
}
// 状态为进行中
if(_this.status === _this.PENDING) {
// 把成功和失败的回调存到对应的队列
_this.onFulfilledCallbacks.push(onFulfilledCallback);
_this.onRejectedCallbacks.push(onRejectedCallback);
}
})
}
// 判断是不是Promise
isPromise(value, resolve, reject){
if (value instanceof MyPromise){
value.then(resolve, reject);
} else {
resolve(value)
}
}
看看执行结果
链式调用成功
then链式调用识别返回的是不是Promise实例本身
原生Promise返回自身会报错
再把then修改一下
then(onFulfilled, onRejected){
const _this = this;
const promise = new MyPromise((resolve, reject) => {
const onFulfilledCallback = () => {
this.isPromise(promise, onFulfilled(_this.value), resolve, reject); // 调用成功的回调,返回value
};
const onRejectedCallback = () => {
this.isPromise(promise, onRejected(_this.reason), resolve, reject); // 调用失败的回调,返回失败原因
};
// 状态为成功时
if (_this.status === _this.FULFILLED) {
onFulfilledCallback();
}
// 状态为失败时
if (_this.status === _this.REJECTED) {
onRejectedCallback();
}
// 状态为进行中
if(_this.status === _this.PENDING) {
// 把成功和失败的回调存到对应的队列
_this.onFulfilledCallbacks.push(onFulfilledCallback);
_this.onRejectedCallbacks.push(onRejectedCallback);
}
})
return promise;
}
// 判断是不是Promise
isPromise(promise, value, resolve, reject){
if (promise === value) {
return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
}
if (value instanceof MyPromise){
value.then(resolve, reject);
} else {
resolve(value)
}
}
报错了,onRejected不是function
做一下容错
then(onFulfilled, onRejected){
const _this = this;
const realOnFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
const realOnRejected = typeof onRejected === 'function' ? onRejected : reason => new Error(reason);
const promise = new MyPromise((resolve, reject) => {
const onFulfilledCallback = () => {
this.isPromise(promise, realOnFulfilled(_this.value), resolve, reject); // 调用成功的回调,返回value
};
const onRejectedCallback = () => {
this.isPromise(promise, realOnRejected(_this.reason), resolve, reject); // 调用失败的回调,返回失败原因
};
// 状态为成功时
if (_this.status === _this.FULFILLED) {
onFulfilledCallback();
}
// 状态为失败时
if (_this.status === _this.REJECTED) {
onRejectedCallback();
}
// 状态为进行中
if(_this.status === _this.PENDING) {
// 把成功和失败的回调存到对应的队列
_this.onFulfilledCallbacks.push(onFulfilledCallback);
_this.onRejectedCallbacks.push(onRejectedCallback);
}
})
return promise;
}
// 判断是不是Promise
isPromise(promise, value, resolve, reject){
if (promise === value) {
return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
}
if (value instanceof MyPromise){
value.then(resolve, reject);
} else {
resolve(value)
}
}
还是报错,promise初始化之前不允许访问
创建一个异步函数,等promise初始化完成后再去执行
then(onFulfilled, onRejected){
const _this = this;
const realOnFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
const realOnRejected = typeof onRejected === 'function' ? onRejected : reason => new Error(reason);
const promise = new MyPromise((resolve, reject) => {
const onFulfilledCallback = () => {
queueMicrotask(this.isPromise(promise, realOnFulfilled(_this.value), resolve, reject));
};
const onRejectedCallback = () => {
queueMicrotask(this.isPromise(promise, realOnRejected(_this.reason), resolve, reject)); // 调用失败的回调,返回失败原因
};
// 状态为成功时
if (_this.status === _this.FULFILLED) {
onFulfilledCallback();
}
// 状态为失败时
if (_this.status === _this.REJECTED) {
onRejectedCallback();
}
// 状态为进行中
if(_this.status === _this.PENDING) {
// 把成功和失败的回调存到对应的队列
_this.onFulfilledCallbacks.push(onFulfilledCallback);
_this.onRejectedCallbacks.push(onRejectedCallback);
}
})
return promise;
}
执行成功
catch方法
错误捕获
catch (onRejected) { return this.then(undefined, onRejected) }
class MyPromise {
PENDING = 'pending';
FULFILLED = 'fulfilled';
REJECTED = 'rejected';
status; // 状态
value = null; // 成功的返回的value
reason = null; // 失败原因
onFulfilledCallbacks = [];
onRejectedCallbacks = [];
constructor(executor) {
try {
// 初始化状态
this.status = this.PENDING;
// 这是Promise接收的函数,立即执行
executor(
this._resolve.bind(this),
this._reject.bind(this)
) // 传入Promise成功和失败的回调
} catch (error) {
this._reject(error);
}
}
// 失败的回调
_reject(reason) {
// 修改状态为失败
if (this.status === this.PENDING) {
// 修改状态和reason值
this.status = this.REJECTED;
this.reason = reason;
while (this.onRejectedCallbacks.length) {
// 执行失败队列中的回调
this.onRejectedCallbacks.shift()(reason);
}
}
}
// 成功的回调
_resolve(value) {
// 修改状态为成功
if (this.status === this.PENDING) {
// 修改状态和reason值
this.status = this.FULFILLED;
this.value = value;
while (this.onFulfilledCallbacks.length) {
// 执行成功队列中的回调
this.onFulfilledCallbacks.shift()(value);
}
}
}
then(onFulfilled, onRejected){
const _this = this;
const realOnFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
const realOnRejected = typeof onRejected === 'function' ? onRejected : reason => new Error(reason);
const promise = new MyPromise((resolve, reject) => {
const onFulfilledCallback = () => {
try{
queueMicrotask(() => this.isPromise(promise, realOnFulfilled(_this.value), resolve, reject));
} catch(error) {
reject(error);
}
};
const onRejectedCallback = () => {
try{
// 调用失败的回调,返回失败原因
queueMicrotask(() => this.isPromise(promise, realOnRejected(_this.reason), resolve, reject));
} catch(error) {
reject(error);
}
};
// 状态为成功时
if (_this.status === _this.FULFILLED) {
onFulfilledCallback();
}
// 状态为失败时
if (_this.status === _this.REJECTED) {
onRejectedCallback();
}
// 状态为进行中
if(_this.status === _this.PENDING) {
// 把成功和失败的回调存到对应的队列
_this.onFulfilledCallbacks.push(onFulfilledCallback);
_this.onRejectedCallbacks.push(onRejectedCallback);
}
})
return promise;
}
catch (onRejected) { return this.then(undefined, onRejected) }
// 判断是不是Promise
isPromise(promise, value, resolve, reject){
// console.log(promise,value)
if (promise === value) {
return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
}
if (value instanceof MyPromise){
value.then(resolve, reject);
} else {
resolve(value)
}
}
}
实现Promise 静态方法
static resolve(value){
if (value instanceof MyPromise) return value;
return new MyPromise((resolve) => resolve(value));
}
static reject(reason){
if (reason instanceof MyPromise) return reason;
return new MyPromise((resolve, reject) => reject(reason));
}
static all(list){
return new MyPromise((resolve, reject) => {
if (Array.isArray(list)) {
reject(new TypeError('is not Array'))
}
let values = [];
let promises = [...list];
let count = 0;
while(promises.length <=) {
this.resolve(promises.shift()).then((res) => {
count ++;
values.push(res)
if (count === promises.length) resolve(values);
}, error => {
return reject(error);
})
}
})
}
static race(list){
return new MyPromise((resolve, reject) => {
if (Array.isArray(list)) {
reject(new TypeError('is not Array'))
}
let promises = [...list];
while(promises.length <=) {
this.resolve(promises.shift()).then((res) => {
return resolve(values);
}, error => {
return reject(error);
})
}
})
}
static finally (cb) {
return this.then(
value => MyPromise.resolve(cb()).then(() => value),
reason => MyPromise.resolve(cb()).then(() => { throw reason })
);
};
static allSettled(list) {
return new MyPromise((resolve, reject) => {
let arr = [];
let count = 0;
for (let p of list) {
this.resolve(p).then(res => {
arr.push({ status: 'fulfilled', value: res});
count++;
if (count === list.length) {
resolve(arr);
}
}).catch(error => {
arr.push({ status: 'rejected', reason: error});
count++;
if (count === list.length) {
resolve(arr);
}
});
};
});
}