本文带大家手写promise,和官方的promise保持一致可以互操作,关于promise的基础知识这里就不再过多赘述了,网上有很多资料,如果有不懂的大家可以上网查阅其它资料 代码地址gitee
jsclass MyPromise {
constructor(executor) {
// 实例化Promise时必须传入一个执行器函数,该函数接收两个参数 resolve和reject用来改变promise的状态
executor(this.resolve.bind(this),this.reject.bind(this))
}
resolve () {
}
reject () {
}
}
jsclass MyPromise {
// 私有属性,防止外部修改该属性的值
#PromiseState = PENDING;
#PromiseResult = undefined;
#onFulfilledCallbacks = []; // 保存成功时的回调函数
#onRejectedCallbacks = []; // 保存失败时的回调函数
constructor(executor) {
// 实例化Promise时必须传入一个执行器函数,该函数接收两个参数 resolve和reject用来改变promise的状态
executor(this.resolve.bind(this),this.reject.bind(this))
}
resolve (result) {
if (this.#PromiseState !== PENDING) return;
this.#PromiseState = FULFILLED;
this.#PromiseResult = result;
this.#onFulfilledCallbacks.forEach(callback => {
callback(result)
})
}
reject (reason) {
if (this.#PromiseState !== PENDING) return;
this.#PromiseState = REJECTED;
this.#PromiseResult = reason;
this.#onRejectedCallbacks.forEach(callback => {
callback(reason)
})
}
}
jsconst PENDING = 'PENDING';
const FULFILLED = 'FULFILLED';
const REJECTED = 'REJECTED';
class MyPromise {
// 私有属性,防止外部修改该属性的值
#PromiseState = PENDING;
#PromiseResult = undefined;
#onFulfilledCallbacks = []; // 保存成功时的回调函数
#onRejectedCallbacks = []; // 保存失败时的回调函数
constructor(executor) {
try {
// 实例化Promise时必须传入一个执行器函数,该函数接收两个参数 resolve和reject用来改变promise的状态
executor(this.resolve.bind(this), this.reject.bind(this))
} catch (error) {
this.reject(error);
}
}
resolve (result) {
if (this.#PromiseState !== PENDING) return;
this.#PromiseState = FULFILLED;
this.#PromiseResult = result;
this.#onFulfilledCallbacks.forEach(callback => {
callback(result)
})
}
reject (reason) {
if (this.#PromiseState !== PENDING) return;
this.#PromiseState = REJECTED;
this.#PromiseResult = reason;
this.#onRejectedCallbacks.forEach(callback => {
callback(reason)
})
}
// 链式调用的then方法
// 该方法接收两个参数 onFulfilled 和 onRejected,它们都是可选的,分别表示当Promise状态变为fulfilled和rejected时的回调函数
then (onFulfilled, onRejected) {
let promise2 = new MyPromise((resolve, reject) => {
if (this.#PromiseState === FULFILLED) {
runMicroTask(() => {
try {
if (typeof onFulfilled !== 'function') {
resolve(this.#PromiseResult);
} else {
let x = onFulfilled(this.#PromiseResult);
resolvePromise(promise2, x, resolve, reject);
}
} catch (e) {
reject(e);
}
})
} else if (this.#PromiseState === REJECTED) {
runMicroTask(() => {
try {
if (typeof onRejected !== 'function') {
reject(this.#PromiseResult);
} else {
let x = onRejected(this.#PromiseResult);
resolvePromise(promise2, x, resolve, reject);
}
} catch (e) {
reject(e);
}
})
} else {
this.#onFulfilledCallbacks.push(() => {
runMicroTask(() => {
try {
if (typeof onFulfilled !== 'function') {
resolve(this.#PromiseResult);
} else {
let x = onFulfilled(this.#PromiseResult);
resolvePromise(promise2, x, resolve, reject);
}
} catch (e) {
reject(e);
}
})
});
this.#onRejectedCallbacks.push(() => {
runMicroTask(() => {
try {
if (typeof onRejected !== 'function') {
reject(this.#PromiseResult);
} else {
let x = onRejected(this.#PromiseResult);
resolvePromise(promise2, x, resolve, reject);
}
} catch (e) {
reject(e);
}
})
});
}
})
return promise2
}
}
runMicroTask = (task) => {
//queueMicrotask(task);
if (typeof process !== 'undefined' && typeof process.nextTick === 'function') {
// node环境
return process.nextTick(task);
} else if (typeof MutationObserver === "function") {
const ob = new MutationObserver(task);
const textNode = document.createTextNode('1')
ob.observe(textNode, {
characterData: true
})
textNode.data = '2'
} else {
setTimeout(task, 0);
}
}
resolvePromise = (promise2, x, resolve, reject) => {
// 2.3.1规范 如果 promise 和 x 指向同一对象,以 TypeError 为据因拒绝执行 promise
if (x === promise2) {
throw new TypeError('Chaining cycle detected for promise');
}
if (x instanceof MyPromise) {
/**
* 2.3.2 如果 x 为 Promise ,则使 promise2 接受 x 的状态
* 也就是继续执行x,如果执行的时候拿到一个y,还要继续解析y
*/
x.then(y => {
resolvePromise(promise2, y, resolve, reject);
}, reject)
} else if (x !== null && ((typeof x === 'object' || (typeof x === 'function')))) {
// 2.3.3 如果 x 为对象或函数
try {
// 2.3.3.1 把 x.then 赋值给 then
var then = x.then;
} catch (e) {
// 2.3.3.2 如果取 x.then 的值时抛出错误 e ,则以 e 为据因拒绝 promise
return reject(e);
}
/**
* 2.3.3.3
* 如果 then 是函数,将 x 作为函数的作用域 this 调用之。
* 传递两个回调函数作为参数,
* 第一个参数叫做 `resolvePromise` ,第二个参数叫做 `rejectPromise`
*/
if (typeof then === 'function') {
// 2.3.3.3.3 如果 resolvePromise 和 rejectPromise 均被调用,或者被同一参数调用了多次,则优先采用首次调用并忽略剩下的调用
let called = false; // 避免多次调用
try {
then.call(x,
// 2.3.3.3.1 如果 resolvePromise 以值 y 为参数被调用,则运行 [[Resolve]](promise, y)
y => {
if (called) return;
called = true;
resolvePromise(promise2, y, resolve, reject);
},
// 2.3.3.3.2 如果 rejectPromise 以据因 r 为参数被调用,则以据因 r 拒绝 promise
r => {
if (called) return;
called = true;
reject(r);
}
)
} catch (error) {
/**
* 2.3.3.3.4 如果调用 then 方法抛出了异常 e
* 2.3.3.3.4.1 如果 resolvePromise 或 rejectPromise 已经被调用,则忽略之
*/
if (called) return;
called = true;
// 2.3.3.3.4.2 否则以 e 为据因拒绝 promise
reject(error);
}
} else {
// 2.3.3.4 如果 then 不是函数,以 x 为参数执行 promise
resolve(x);
}
} else {
// 2.3.4 如果 x 不为对象或者函数,以 x 为参数执行 promise
return resolve(x);
}
};
isPromiseLike = (value) => {
return value && typeof value.then === 'function';
}



本文作者:繁星
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!