css
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);
});
其他静态方法
css
static resolve(value) {
return new MyPromise((resolve) => resolve(value));
}
static reject(reason) {
return new MyPromise((resolve, reject) => reject(reason));
}
static all(promises) {
// 问题关键: 什么时候要执行resolve, 什么时候要执行reject
return 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所有的都失败才执行reject
const 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));
}
});
});
});
}