手写Promise
构造器的实现
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected'class MyPromise{#state = PENDING;#result = undefined;constructor(executor){const resolve = (data) => {this.#changeState(FULFILLED, data);};const reject = (reason) => {this.#changeState(REJECTED, reason);};try {executor(resolve, reject);} catch (err) {reject(err);} }#changeState(state, result){if(this.#state !== PENDING) return;this.#state = state;this.#result = result;}
}
const p = new MyPromise((resolve, reject) =>{resolve(1);
});
- Promise 的状态一旦定下来之后,在后续的所有过程中都不可能再去改变它的状态了
- 如果再执行过程中报错,会执行rejected,但是捕获不到异步错误
Promise-then的回调执行时机
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected'class MyPromise{#state = PENDING;#result = undefined;#handlers = [];constructor(executor){const resolve = (data) => {this.#changeState(FULFILLED, data);};const reject = (reason) => {this.#changeState(REJECTED, reason);};try {executor(resolve, reject);} catch (err) {reject(err);} }#changeState(state, result){if(this.#state !== PENDING) return;this.#state = state;this.#result = result;this.#run();}#run(){if(this.#state === PENDING) return;while(this.#handlers.length){const {onFulfilled, onRejected, resolve, reject} = this.#handlers.shift();if(this.#state === FULFILLED){if(typeof onFulfilled === 'function'){onFulfilled(this.#result)}}else{if(typeof onRejected === 'function'){onRejected(this.#result)}}}}then(onFulfilled, onRejected){return new MyPromise((resolve, reject) =>{this.#handlers.push({onFulfilled,onRejected,resolve,reject,});this.#run();});}
}const p = new MyPromise((resolve, reject) =>{setTimeout(()=>{resolve(123);},1000)
});p.then((res) =>{console.log('promise 成功1', res);}, (err) =>{console.log('promise 失败1', err);}
);
p.then((res) =>{console.log('promise 成功2', res);}, (err) =>{console.log('promise 失败2', err);}
);
p.then((res) =>{console.log('promise 成功3', res);}, (err) =>{console.log('promise 失败3', err);}
);
为了判断什么时候调用,所以用一个handlers数组记录,并用run函数调用
Promise-then 的返回值
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected'class MyPromise{#state = PENDING;#result = undefined;#handlers = [];constructor(executor){const resolve = (data) => {this.#changeState(FULFILLED, data);};const reject = (reason) => {this.#changeState(REJECTED, reason);};try {executor(resolve, reject);} catch (err) {reject(err);} }#changeState(state, result){if(this.#state !== PENDING) return;this.#state = state;this.#result = result;this.#run();}// 判断一个函数是不是Promise(是否满足A+规范)#isPromiseLike(value){return value && typeof value.then === 'function' && (typeof value === 'object' || typeof value === 'function');}// 把一个函数放到微队列#runMicroTask(func){// node nextTickif(process && process.nextTick){process.nextTick(func);}// 浏览器 MutationObserverelse if(typeof MutationObserver === 'function'){const ob = new MutationObserver(fn);const text = document.createTextNode('1');ob.observe(text, { characterData: true});text.data = '2';}else{setTimeout(fn, 0);}}#runOne(callback, resolve, reject){this.#runMicroTask(()=>{if(typeof callback !== 'function'){const settled = this.#state === FULFILLED ? resolve : reject;settled(this.#result);return;}try {const data = callback(this.#result);if(this.#isPromiseLike(data)){data.then(resolve, reject);}else{resolve(data);}} catch (err) {reject(err);}});}#run(){if(this.#state === PENDING) return;while(this.#handlers.length){const {onFulfilled, onRejected, resolve, reject} = this.#handlers.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.#handlers.push({onFulfilled,onRejected,resolve,reject,});this.#run();});}
}const p = new MyPromise((resolve, reject) =>{setTimeout(()=>{reject(123);},1000)
});p.then(null, (err) =>{console.log('promise 失败', err);return 456;}
).then((data) =>{console.log("ok",data);
});
这里有三种情况:
- 对应的回调不是函数的情况
- 回调是一个函数的情况
- 返回结果是一个Promise的情况