class MyPromise {
constructor(fn) {
this.status = 'pedding';
this.value = undefined; //成功理由
this.reason = undefined; //失败理由
this.onFulfilledList = [];
this.onRejectedList = [];
const resolve = (result) => {
setTimeout(() => {
if (this.status === 'pedding') {
this.status = 'resolved';
this.value = result;
this.onFulfilledList.forEach((fn) => fn(this.value));
}
}, 0);
};
const reject = (error) => {
setTimeout(() => {
if (this.status === 'pedding') {
this.status = 'rejected';
this.reason = error;
this.onRejectedList.forEach((fn) => fn(this.reason));
}
}, 0);
};
try {
fn(resolve, reject);
} catch (error) {
reject(error);
}
}
then(onFulfilled, onRejected) {
if (this.status === 'pedding') {
return new MyPromise((resolve, reject) => {
this.onFulfilledList.push(() => {
try {
const x = onFulfilled(this.value);
if (x instanceof MyPromise) {
x.then(resolve, reject);
} else {
resolve(x);
}
} catch (error) {
reject(error);
}
});
this.onRejectedList.push(() => {
try {
const x = onFulfilled(this.value);
if (x instanceof MyPromise) {
x.then(resolve, reject);
} else {
resolve(x);
}
} catch (error) {
reject(error);
}
});
});
} else if (this.status === 'resolved') {
onFulfilled(this.value);
} else if (this.status === 'rejected') {
onRejected(this.reason);
}
}
}