Skip to main content

MyPromise

class MyPromise {
// 定义三种状态
static PENDING = 'pending';
static FULFILLED = 'fulfilled';
static REJECTED = 'rejected';

constructor(executor) {
// 初始化状态
this.state = MyPromise.PENDING;
this.value = undefined; // 成功的值
this.reason = undefined; // 失败的原因
// 保存 then 回调,因为可能多次调用 then 且状态未立即改变
this.onFulfilledCallbacks = [];
this.onRejectedCallbacks = [];

// resolve 函数
const resolve = (value) => {
if (this.state === MyPromise.PENDING) {
// 如果 value 本身是一个 MyPromise 实例
if (value instanceof MyPromise) {
value.then(resolve, reject);
return;
}
this.state = MyPromise.FULFILLED;
this.value = value;
// 依次执行所有成功回调
this.onFulfilledCallbacks.forEach(fn => fn());
}
};

// reject 函数
const reject = (reason) => {
if (this.state === MyPromise.PENDING) {
// 如果 reason 本身是一个 MyPromise 实例
if (reason instanceof MyPromise) {
reason.then(resolve, reject);
return;
}
this.state = MyPromise.REJECTED;
this.reason = reason;
this.onRejectedCallbacks.forEach(fn => fn());
}
};

// 执行 executor,捕获同步异常
try {
executor(resolve, reject);
} catch (err) {
reject(err);
}
}

// then 方法:返回一个新的 Promise 实现链式调用
then(onFulfilled, onRejected) {
// 值穿透:如果参数不是函数,则将其视为值传递函数
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason };

const newPromise = new MyPromise((resolve, reject) => {
// 封装异步调用,确保回调在微任务(或宏任务)中执行
const handleCallback = (callback, arg, resolve, reject) => {
queueMicrotask(() => {
try {
const result = callback(arg);
resolvePromise(newPromise, result, resolve, reject);
} catch (err) {
reject(err);
}
});
};

if (this.state === MyPromise.FULFILLED) {
handleCallback(onFulfilled, this.value, resolve, reject);
} else if (this.state === MyPromise.REJECTED) {
handleCallback(onRejected, this.reason, resolve, reject);
} else {
// pending 状态,保存回调
this.onFulfilledCallbacks.push(() =>
handleCallback(onFulfilled, this.value, resolve, reject)
);
this.onRejectedCallbacks.push(() =>
handleCallback(onRejected, this.reason, resolve, reject)
);
}
});

return newPromise;
}

// catch 方法:then(null, onRejected) 的语法糖
catch(onRejected) {
return this.then(null, onRejected);
}

// finally 方法:无论成功或失败都会执行,返回原值或原因
finally(callback) {
return this.then(
value => MyPromise.resolve(callback()).then(() => value),
reason => MyPromise.resolve(callback()).then(() => { throw reason })
);
}

// 静态方法 resolve
static resolve(value) {
if (value instanceof MyPromise) return value; // 展平
return new MyPromise(resolve => resolve(value));
}

// 静态方法 reject
static reject(reason) {
return new MyPromise((_, reject) => reject(reason));
}

// 静态方法 all
static all(promises) {
return new MyPromise((resolve, reject) => {
if (!Array.isArray(promises)) {
return reject(new TypeError('promises must be an array'));
}
const results = [];
let completed = 0;
if (promises.length === 0) {
resolve(results);
return;
}
promises.forEach((p, index) => {
MyPromise.resolve(p).then(
value => {
results[index] = value;
completed++;
if (completed === promises.length) resolve(results);
},
reject
);
});
});
}

// 静态方法 race
static race(promises) {
return new MyPromise((resolve, reject) => {
if (!Array.isArray(promises)) {
return reject(new TypeError('promises must be an array'));
}
promises.forEach(p => {
MyPromise.resolve(p).then(resolve, reject);
});
});
}
}

// 辅助函数:处理 then 回调返回值,实现链式解析
function resolvePromise(promise, x, resolve, reject) {
// 防止循环引用
if (promise === x) {
return reject(new TypeError('Chaining cycle detected for promise'));
}

// 如果 x 是一个 Promise,则等待它的结果
if (x instanceof MyPromise) {
x.then(resolve, reject);
return;
}

// 如果 x 是对象或函数,尝试将其作为 thenable 处理
if (x !== null && (typeof x === 'object' || typeof x === 'function')) {
let then;
try {
then = x.then;
} catch (err) {
return reject(err);
}
if (typeof then === 'function') {
let called = false; // ① 防止重复决议
try {
then.call(
x, // ② 把 x 作为 then 方法的 this
y => { // ③ 成功回调(resolve)
if (called) return;
called = true;
resolvePromise(promise, y, resolve, reject); // 递归解析 y
},
r => { // ④ 失败回调(reject)
if (called) return;
called = true;
reject(r);
}
);
} catch (err) { // ⑤ 调用 then 时抛出的异常
if (called) return;
reject(err);
}
}
} else {
// 普通值直接 resolve
resolve(x);
}
}

// 测试示例(可选)
/*
const p = new MyPromise((resolve, reject) => {
setTimeout(() => resolve('success'), 100);
});
p.then(res => {
console.log(res); // success
return 'next';
}).then(res => {
console.log(res); // next
});
*/