手写Promise
第一步:实现构造函数(构造器的实现)
第二步:实现then方法
then方法要解决两个问题
第一个问题:then函数的两个参数onFulfilled和onRejected何时执行(then的回调执行时机)
第二个问题:then中返回的Promise什么时候成功,什么时候失败(then的返回值)
处理then的返回值,要分三种情况:
- 对应的回调不是函数(穿透),直接resolve或者reject,是resolve还是reject取决于当前的状态
- 回调是函数,执行过程如果没有报错,拿到返回值调用resolve,如果报错了,调用reject,支持链式调用
- 回调函数的返回结果是一个Promise,则调用它的then方法,将resolve与reject传入
最后需要注意的是要实现一个微队列(因为then的回调是放到微队列里的),需要区分node环境和浏览器环境
还需要实现一个是否是Promise的判断,只要满足Promise A+规范就是Promise,Promise之间具有互操作性
javascript
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
class MyPromise {
#state = 'pending';
#result = undefined;
#handler = [];
constructor(executor) {
const resolve = (data) => {
this.#changeState(FULFILLED, data);
};
const reject = (reason) => {
this.#changeState(REJECTED, reason);
};
try {
executor(resolve, reject);
} catch (reason) {
this.#changeState(REJECTED, reason);
}
}
#changeState(state, result) {
if (this.#state !== PENDING) {
return;
}
this.#state = state;
this.#result = result;
this.#run();
}
#isPromiseLike(value) {
if (value !== null && (typeof value === 'object' || typeof value === 'function')) {
return typeof value.then === 'function';
}
return false;
}
#runMicroTask(func) {
if (typeof process === 'object' && typeof process.nextTick === 'function') {
process.nextTick(func);
} else if (typeof MutationObserver === 'function') {
const observer = new MutationObserver(func);
const textNode = document.createTextNode('1');
observer.observe(textNode, {characterData: true});
textNode.data = '2';
} else {
setTimeout(func, 0);
}
}
#runOne(callback, resolve, reject) {
this.#runMicroTask(() => {
if (typeof callback === 'function') {
try {
const data = callback(this.#result);
if (this.#isPromiseLike(data)) {
data.then(resolve, reject);
} else {
resolve(data);
}
} catch (err) {
reject(err);
}
} else {
const settled = this.#state === FULFILLED ? resolve : reject;
settled(this.#result);
}
})
}
#run() {
if (this.#state === PENDING) {
return;
}
while (this.#handler.length) {
const {onFulfilled, onRejected, resolve, reject} = this.#handler.shift();
if (this.#state === FULFILLED) {
this.#runOne(onFulfilled, resolve, reject);
} else {
this.#runOne(onRejected, resolve, reject);
}
}
}
then(onFulfilled, onRejected) {
return new MyPromise((resolve, reject) => {
this.#handler.push({
onFulfilled,
onRejected,
resolve,
reject,
});
this.#run();
})
}
}
const p = new MyPromise((resolve, reject) => {
resolve(2);
});
p.then(data => {
console.log(data)
})
setTimeout(() => {
console.log(1);
}, 0);
console.log(3);
// 输出3 -> 2 -> 1
设计模式上Promise的实现依托观察者模式。观察内部状态#state的变化触发then函数中的回调函数。