最近在网上看到了一篇挺好的博客,详细地分析了promise的源码和实现原理,大佬的博客,有详细介绍。
不过对于刚入门的同学来说,可能理解起来存在一定的难度。由于时间原因,我也只是看了个大概,很佩服作者对问题严谨的逻辑分析能力。
本着由浅入深学习的理念,我想自己也先模仿着写一个promise实现,做最简单的实现后再添砖加瓦。这样学习起来相对轻松 ,且印象深刻。(大佬请忽视)
const empty = () => {};
class Promise {
constructor(fn) {
this.state ="pending"; // 状态
this.sucQueue = []; // 成功回调函数队列
this.failQueue = []; // 失败回调函数队列
fn(this.resolve.bind(this), this.reject.bind(this)); // 执行实例化promise对象中的函数体
}
resolve(value) {
if (this.state ==="pending") {
this.state ="fullfiled";
let cb;
setTimeout(() => {
while (cb =this.sucQueue.shift()) {
cb(value);
}
}, 0)
}
}
reject(value) {
if (this.state ==="pending") {
this.state ="rejected";
let cb =this.sucQueue.shift();
setTimeout(() => {
while (cb =this.sucQueue.shift()) {
cb(value);
}
}, 0);
}
}
then(sucCb, failCb) {
if (this.state ==="pending") {
this.sucQueue.push(sucCb ||empty);
this.failQueue.push(failCb ||empty);
}
return this; // 实际上源码这里做了处理,返回的是一个新的promise对象,从而可以链式调用
}
catch(failCb) { // catch只是then的语法糖,可以用then(undefined, failCb)代替
if (this.state ==="pending") {
this.failQueue.push(failCb ||empty);
}
return this; // 同上
}
}
// 接下来就是实例化一个promise,并调用实例方法的时候
const p = new Promise(
(resolve) => {
setTimeout(() => {
resolve("123");
}, 5000)
})
p.then((res) => {
console.log("触发成功函数队列中的第一个回调函数", res);
});
p.then((res) => {
console.log("触发成功函数队列中的第二个回调函数", res);
}).catch((res) => {
console.log("由于状态已变更,所以不会再触发catch的回调!")
});
我直接在node环境下运行,输出结果和期望一样。在等待5s后:
图片.png当然这里我们考虑的场景是及其简单的,和源码中的缜密逻辑没法比,不过用来理解起来应该简单的多。
后续我还会模拟静态方法 ,在自己理解的过程中学习进步。
有问题欢迎指出,勿喷,我还是个小菜鸟,o(╥﹏╥)o
网友评论