答案:手写实现Promise需掌握状态管理、异步执行、链式调用和错误传递,核心包括三种状态(pending、fulfilled、rejected)、then方法返回新Promise、resolvePromise处理返回值及catch、resolve、reject等静态方法。
实现一个符合 Promise/A+ 规范的 Promise 并不复杂,但需要理解其核心机制:状态管理、异步执行、链式调用和错误传递。下面是一个简化但功能完整的 Promise 手写实现,帮助你深入理解其工作原理。
1. Promise 的三种状态
Promise 有三种状态:
-
pending:初始状态,未 fulfilled 或 rejected
-
fulfilled:成功状态,值已确定
-
rejected:失败状态,原因已确定
状态一旦从 pending 变为 fulfilled 或 rejected,就不能再改变。
2. 基本结构与状态管理
class MyPromise {
constructor(executor) {
this.status = 'pending';
this.value = undefined;
this.reason = undefined;
this.onFulfilledCallbacks = [];
this.onRejectedCallbacks = [];
const resolve = (value) => {
if (this.status === 'pending') {
this.status = 'fulfilled';
this.value = value;
this.onFulfilledCallbacks.forEach(fn => fn());
}
};
const reject = (reason) => {
if (this.status === 'pending') {
this.status = 'rejected';
this.reason = reason;
this.onRejectedCallbacks.forEach(fn => fn());
}
};
try {
executor(resolve, reject);
} catch (err) {
reject(err);
}
}
then(onFulfilled, onRejected) {
// 处理可选参数
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : val => val;
onRejected = typeof onRejected === 'function' ? onRejected : err => { throw err; };
let promise2;
if (this.status === 'fulfilled') {
return promise2 = new MyPromise((resolve, reject) => {
setTimeout(() => {
try {
let x = onFulfilled(this.value);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
});
});
}
if (this.status === 'rejected') {
return promise2 = new MyPromise((resolve, reject) => {
setTimeout(() => {
try {
let x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
});
});
}
if (this.status === 'pending') {
return promise2 = new MyPromise((resolve, reject) => {
this.onFulfilledCallbacks.push(() => {
setTimeout(() => {
try {
let x = onFulfilled(this.value);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
});
});
this.onRejectedCallbacks.push(() => {
setTimeout(() => {
try {
let x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
});
});
});
}
}
}
3. 处理 then 返回值(resolvePromise)
then 方法返回一个新的 Promise,必须根据回调的返回值决定新 Promise 的状态。这是 Promise/A+ 规范的核心逻辑。
function resolvePromise(promise2, x, resolve, reject) {
if (promise2 === x) {
return reject(new TypeError('Chaining cycle detected for promise'));
}
let called;
if (x != null && (typeof x === 'object' || typeof x === 'function')) {
try {
let then = x.then;
if (typeof then === 'function') {
then.call(x, y => {
if (called) return;
called = true;
resolvePromise(promise2, y, resolve, reject);
}, r => {
if (called) return;
called = true;
reject(r);
});
} else {
resolve(x);
}
} catch (e) {
if (called) return;
called = true;
reject(e);
}
} else {
resolve(x);
}
}
4. 添加 catch 和静态方法
catch 是 then 的语法糖,只处理错误;resolve 和 reject 提供快速创建已决议的 Promise。
MyPromise.prototype.catch = function(onRejected) {
return this.then(null, onRejected);
};
MyPromise.resolve = function(value) {
return new MyPromise(resolve => resolve(value));
};
MyPromise.reject = function(reason) {
return new MyPromise((resolve, reject) => reject(reason));
};
// 可选:实现 all 方法
MyPromise.all = function(promises) {
return new MyPromise((resolve, reject) => {
let result = [];
let count = 0;
if (promises.length === 0) return resolve(result);
for (let i = 0; i {
result[i] = val;
if (++count === promises.length) resolve(result);
},
err => reject(err)
);
}
});
};
基本上就这些。这个手写版本涵盖了 Promise 的核心机制:状态控制、异步任务队列、链式调用和值穿透。虽然省略了一些边界处理,但它能正确运行大多数常见场景,适合学习和面试使用。