js 手写promise
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';class MyPromise {#status = PENDING;#result = undefined;#handler = undefined;constructor(executor) {// 不能写在外面,因为this指向会出问题const resolve = (data) => {this.#changeState(FULFILLED, data);}const reject = (err) => {this.#changeState(REJECTED, err);}try {executor(resolve, reject);} catch(err) {reject(err); }}#changeState (status, result) {if (this.#status !== PENDING) {return;}this.#status = status;this.#result = result;this.#run();}#run () {console.log(this, this.#handler);if (this.status === PENDING) {return;}const { onFulfilled, onRejected, resolve, reject } = this.#handler;// 回调不是函数,那么将当前的promise状态透传// 回调是函数,将函数执行返回值作为新的值传递,状态变为成功,执行过程报错,那么状态就为失败if(this.#status === FULFILLED) {if (typeof onFulfilled === 'function') {try {const res = onFulfilled(this.#result);resolve(res);} catch (err) {reject(err);}} else {resolve(this.#result);}} else {if (typeof onRejected === 'function') {try {const res = onRejected(this.#result);resolve(res);} catch (err) {reject(err);}} else {reject(this.#result);}}}then(onFulfilled, onRejected) {return new MyPromise((resolve, reject) => {this.#handler = { onFulfilled, onRejected, resolve, reject };this.#run();});}
}const p = new Promise((resolve, reject) => {// setTimeout(() => {reject(222);// }, 0);// resolve(111);// throw 123;// setTimeout(() => {// throw 123; // 异步错误捕获不到,Promise也是一样// }, 0);
});p.then((res) => {console.log('成功1', res);
}, (err) => {console.log('失败1', err);return 333;
}).then(1, (err) => {console.log('失败2', err);
}).then((res) => {console.log('成功3', res);
}, (err) => {console.log('失败3', err);
}).then((res) => {console.log('成功4', res);
}, (err) => {console.log('失败4', err);
});const p1 = new MyPromise((resolve, reject) => {// setTimeout(() => {reject(222);// }, 0);// resolve(111);// throw 123;// setTimeout(() => {// throw 123; // 异步错误捕获不到,Promise也是一样// }, 0);
});p1.then((res) => {console.log('成功1', res);
}, (err) => {console.log('失败1', err);return 333;
}).then(1, (err) => {console.log('失败2', err);
}).then((res) => {console.log('成功3', res);
}, (err) => {console.log('失败3', err);
}).then((res) => {console.log('成功4', res);
}, (err) => {console.log('失败4', err);
});
其他静态方法
static resolve(value) {return new MyPromise((resolve) => resolve(value));}static reject(reason) {return new MyPromise((resolve, reject) => reject(reason));}static all(promises) {// 问题关键: 什么时候要执行resolve, 什么时候要执行rejectreturn new MyPromise((resolve, reject) => {const values = [];promises.forEach((promise) => {promise.then((res) => {values.push(res);if (values.length === promises.length) {resolve(values);}},(err) => {reject(err);},);});});}static allSettled(promises) {return new MyPromise((resolve) => {const results = [];promises.forEach((promise) => {promise.then((res) => {results.push({ status: PROMISE_STATUS_FULFILLED, value: res });if (results.length === promises.length) {resolve(results);}},(err) => {results.push({ status: PROMISE_STATUS_REJECTED, value: err });if (results.length === promises.length) {resolve(results);}},);});});}static race(promises) {return new MyPromise((resolve, reject) => {promises.forEach((promise) => {promise.then(resolve, reject);});});}static any(promises) {// resolve必须等到有一个成功的结果// reject所有的都失败才执行rejectconst reasons = [];return new MyPromise((resolve, reject) => {promises.forEach((promise) => {promise.then(resolve, (err) => {reasons.push(err);if (reasons.length === promises.length) {reject(new AggregateError(reasons));}});});});}