/**
* 任何符合promise规范的对象或函数都可以成为promise,promise A plus 规范地址 https://promisesaplus.com
*/
class MyPromise {
// Promise 的三种状态
static PENDING = "PENDING";
static FULFILLED = "FULFILLED";
static REJECTED = "REJECTED";
// 实现 静态方法 resolve
static resolve(value) {
return new MyPromise((resolve) => resolve(value));
}
// 实现静态方法 reject
static reject(reason) {
return new MyPromise((resolve, reject) => reject(reason));
}
// 实现静态方法 all
static all() {}
// 实现静态方法 allSettle
static allSettle() {}
// 实现静态方法 race
static race() {}
/**
* 核心:构造器的代码及思路
* @param executor
* @param name
*/
constructor(executor, name) {
// 1. 判断 executor 是否是否是函数,如过不是抛出错误
if (typeof executor !== "function") {
throw new Error(`Promise resolver is not a function`);
}
// 2. 初始化 _status 用来保存当前 promise 实例的状态值
this._status = MyPromise.PENDING;
// 3. 初始化 _value 用来保存当前 promise 的结果值
this._value = undefined;
// 4. 初始化 _callbacks 队列 用来保存各种回调,在产生结果时依次调用
this._callbacks = [];
// 5. 立即调用 executor 函数执行,并将改变 promise 状态,处理结果的函数当参数传递,供使用者调用,注意要绑定好 this 指向
try {
executor(this._onResolve.bind(this), this._onReject.bind(this));
} catch (e) {
// 6、当 executor 调用产生错误时,直接给内部 _onReject 处理
this._onReject(e);
}
}
/**
* 如何改变 promise 为成功值,并处理结果
* @param value
* @private
*/
_onResolve(value) {
// 1、判断状态值是否时pending状态
if (this._status !== MyPromise.PENDING) return;
// 2、将状态值改为 fulfilled 状态
this._status = MyPromise.FULFILLED;
// 3、判断用户传来的结果时不是 promise
let valueIsPromise = value instanceof MyPromise;
// 4、定义用户传来promise时的状态
let _status = MyPromise.PENDING;
// 5、如果是 promise 实例,需要给 promise 绑定上 then 方法 进行数据处理
if (valueIsPromise) {
value.then(
(value) => {
this._value = value;
_status = MyPromise.FULFILLED;
},
(reason) => {
this._value = reason;
_status = MyPromise.REJECTED;
}
);
} else {
this._value = value;
}
// 6、利用setTime模拟微任务
setTimeout(() => {
// 7、同一个promise 可能回绑定多个 then 方法,所以需要用数组存储
this._callbacks
.forEach(({ onfulfilled, onrejected, resolve, reject }) => {
try {
// 8、处理 promise 结果
if (valueIsPromise && _status === MyPromise.REJECTED && typeof onrejected === 'function') {
return resolve(onrejected(this._value));
}
if (typeof onfulfilled === 'function') {
return resolve(onfulfilled(this._value))
}
} catch (e) {
reject(e);
}
});
}, 0);
}
_onReject(reason) {
// 1、判断状态值是否时pending状态
if (this._status !== MyPromise.PENDING) return;
// 2、将状态值改为 rejected 状态
this._status = MyPromise.REJECTED;
// 3、直接将结果赋值
this._value = reason;
setTimeout(() => {
// 4、筛选出含有 onrejected 的callback
const onrejectedCallbacks = this._callbacks.filter(
({ onrejected }) => typeof onrejected === "function"
);
// 5、如果没有错误处理的函数,直接将错误抛出
if (onrejectedCallbacks.length === 0) throw this._value;
onrejectedCallbacks.forEach(({ onrejected, resolve, reject }) => {
// 6、处理结果
try {
resolve(onrejected(this._value))
} catch (e) {
reject(e);
}
});
}, 0);
}
/*
* then 有两个参数:onfulfilled onrejected
* then 调用回返回一个新的Promise实例
* 通过将 新promise实例的 resolve、reject 传入callbacks中,在处理完 onfulfilled 、 onrejected时调用
* 这样就可以构成链式调用并将上次结果传到下一个promise里
*/
then(onfulfilled, onrejected) {
return new MyPromise((resolve, reject) => {
this._callbacks.push({
onfulfilled,
onrejected,
resolve,
reject,
});
});
}
/*
* 只处理错误的结果
*/
catch(onrejected) {
this.then(undefined, onrejected)
}
finally() {}
}
简易版实现Promise
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- 一直在用fetch进行网络请求,我都知道fetch是支持Promise的,突发奇想想要自己实现一个简易版的基于Pr...
- 最简易版本 promise 源码 思路整理分析正常使用时候如何实例化调用,认知梳理需求。由调用可知,一个 prom...
- 前言 之前在 上篇[https://www.mghio.cn/post/558ca0bd.html] 提到过会实现...