Promise 和 Promise/A+ 规范
Promise详解与实现(Promise/A+规范) - 简书 (jianshu.com)
简易版 Promise 实现
class Promise {
constructor(executor) {
this.state = "pending";
this.value = undefined;
this.reason = undefined;
let resolve = (value) => {
if (this.state === "pending") {
this.state = "resolved";
this.value = value;
}
};
let reject = (reason) => {
if (this.state === "pending") {
this.state = "rejected";
this.reason = reason;
}
};
try {
executor(resolve, reject);
} catch (err) {
reject(err);
}
}
then(onResolved, onRejected) {
if (this.state === "resolved") {
onResolved(this.value);
}
if (this.state === "rejected") {
onRejected(this.reason);
}
}
}
Promise/A+ 规范要点
补充:Promise/A+ 规范定义了一个 thenable 必须满足的契约,面试常考点:
- 状态机必须是
pending→fulfilled或pending→rejected,状态一旦确定不可再变; then的两个参数onFulfilled、onRejected都是可选的,缺省时透传值/异常;- 同一个 promise 上的
then必须按注册顺序依次执行; then必须返回一个新的 promise,支持链式调用;onFulfilled/onRejected必须异步执行(推到微任务队列)。
满足 A+ 规范的最小实现(异步版)
const PENDING = "pending";
const FULFILLED = "fulfilled";
const REJECTED = "rejected";
function Promise(executor) {
this.state = PENDING;
this.value = undefined;
this.reason = undefined;
this.onFulfilledCallbacks = [];
this.onRejectedCallbacks = [];
const resolve = (value) => {
if (this.state === PENDING) {
this.state = FULFILLED;
this.value = value;
this.onFulfilledCallbacks.forEach((cb) => cb());
}
};
const reject = (reason) => {
if (this.state === PENDING) {
this.state = REJECTED;
this.reason = reason;
this.onRejectedCallbacks.forEach((cb) => cb());
}
};
try {
executor(resolve, reject);
} catch (err) {
reject(err);
}
}
Promise.prototype.then = function (onFulfilled, onRejected) {
return new Promise((resolve, reject) => {
const handleFulfilled = () =>
queueMicrotask(() => {
try {
const x = onFulfilled ? onFulfilled(this.value) : this.value;
resolve(x);
} catch (e) {
reject(e);
}
});
const handleRejected = () =>
queueMicrotask(() => {
try {
const x = onRejected ? onRejected(this.reason) : this.reason;
resolve(x); // 这里简化为透传,生产实现需区分 resolvePromise
} catch (e) {
reject(e);
}
});
if (this.state === FULFILLED) handleFulfilled();
else if (this.state === REJECTED) handleRejected();
else {
this.onFulfilledCallbacks.push(handleFulfilled);
this.onRejectedCallbacks.push(handleRejected);
}
});
};



