持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第28天,点击查看活动详情
前言
Promise
也是面试中常考的问题,在日常工作中倒是常常用到,但真要让我说一下,我还真的说不出来,所以我这里直接截图阮一峰《# ECMAScript 6 入门》的定义:
Promise
对三种状态:Pending、fullfiled、reject
,两个特点状态变化不受外界影响、一旦状态改变,就不会再变,任何时候都可以得到这个结果,接下来我就带大姐来实现一个简单的Promise
。
1.首先我们来定义三个静态变量保存Promise
的三种状态。
class MyPromise {
// 定义promise3种状态 pending fulfilled rejected
static Pending = "pending";
static Fulfilled = "fulfilled";
static Rejected = "rejected";
}
2.下来再定义constructor
构造函数,该函数接受一个回调函数
constructor(callback) {
this.promiseStatus = MyPromise.Pending; // 状态
this.promiseResult = null; // 执行结果
this.fulfilledCallbacks = []; // 成功调用栈
this.rejectedCallbacks = []; // 失败调用栈
try {
callback(this.resolve.bind(this), this.reject.bind(this)); // 执行传入的函数
} catch (err) {
console.log(111, err);
this.reject(err);
}
}
3.实现成功回调函数resolve
.
// 实现resolve
resolve(result) {
setTimeout(() => {
if (this.promiseStatus == "pending") {
this.promiseStatus = "fulfilled";
this.promiseResult = result;
this.fulfilledCallbacks.forEach((callback) => { // 循环调用成功回调函数
callback(result);
});
}
});
}
我们用setTimeout
来模拟异步,当状态为pending
时,将成功结果赋值给Promise
执行结果,并循环执行成功回调函数,执行完毕后,Promise
状态由pending
变为fullfilled
。
4.实现失败回调函数reject
该函数接收Promise
回调函数执行失败的的原因作为参数。
// 实现reject
reject(reason) {
setTimeout(() => {
if (this.promiseStatus == "pending") {
this.promiseStatus = "rejected"; // 执行后将状态变更为rejected
this.promiseResult = reason; // 返回失败原因
this.rejectedCallbacks.forEach((callback) => { // 循环执行失败回调
callback(reason);
});
}
});
}
5.实现then链式调用
该函数接收成功回调和失败回调作为参数
then(onFulfilled, onRejected) {
onFulfilled =
typeof onFulfilled == "function"
? onFulfilled
: (value) => {
return value;
}; // 如果有传入的成功回调函数,直接使用,没有就把传入值作为返回值
onRejected =
typeof onRejected === "function"
? onRejected
: (reason) => {
return reason;
}; // // 如果有传入的失败回调函数,直接使用,没有就把传入值作为返回值
if (this.promiseStatus == "pending") { // 如果是pending状态 则将两个回调分别加入回调栈中
this.fulfilledCallbacks.push(onFulfilled);
this.rejectedCallbacks.push(onRejected);
}
if (this.promiseStatus == "fulfilled") { // 成功则加入成功回调栈
setTimeout(() => {
onFulfilled(this.promiseResult);
});
}
if (this.promiseStatus == "rejected") { // 失败加入失败回调
setTimeout(() => {
onRejected(this.promiseResult);
});
}
}
6.代码验证
const promise = new MyPromise((resolve, reject) => {
setTimeout(() => {
resolve('success')
}, 2000);
})
promise.then(value => {
console.log(1)
console.log('resolve', value)
})
promise.then(value => {
console.log(2)
console.log('resolve', value)
})
promise.then(value => {
console.log(3)
console.log('resolve', value)
})
打印执行顺序
如果将
resolve('success')
改为reject('fail')
,则只答应三个fail
,catche
还未实现。
以上就是简易版Promise的实现
,喜欢就点个赞吧。