promise核心是状态不可逆(pending→fulfilled/rejected)及.then()返回新promise实现链式调用;其关键逻辑在于:同步返回新promise,异步执行回调,按返回值类型(普通值/thenable)决定新promise状态。

理解 Promise 构造函数与状态流转是基础
手动实现一个简易 Promise,关键在于抓住三个核心:初始状态(pending)、成功态(fulfilled)、失败态(rejected),以及状态**不可逆**这一约束。一旦从 pending 变为 fulfilled 或 rejected,后续所有状态变更都会被忽略。这直接决定了 .then() 回调为何只在“确定结果后”才执行,且不会因多次 resolve/reject 而重复触发。
手写 Promise.prototype.then() 的核心逻辑
.then() 不是简单地把回调存起来——它必须返回一个**新的 Promise**,这是链式调用能成立的前提。否则,连续调用 .then().then() 就会断掉。手写时需注意:
- 无论上一个 Promise 是成功还是失败,.then() 都要同步返回新 Promise(即 new Promise(...))
- 当上一个 Promise 已 settled(fulfilled/rejected),需异步(如 setTimeout 或 queueMicrotask)执行对应 onFulfilled/onRejected,并用其返回值决定新 Promise 的状态
- 如果 onFulfilled/onRejected 抛出错误,新 Promise 应以该错误 reject
- 如果 onFulfilled/onRejected 返回的是另一个 Promise(即“可 thenable 对象”),新 Promise 的状态应**跟随它**(即 resolve 时等它完成,reject 时立即 reject)
用最简代码验证链式行为
下面是一个极简但可运行的手写 Promise(仅支持基本链式):
function MyPromise(executor) {
let state = 'pending';
let value = undefined;
let reason = undefined;
let onFulfilledCbs = [];
let onRejectedCbs = [];
<p>function resolve(val) {
if (state === 'pending') {
state = 'fulfilled';
value = val;
onFulfilledCbs.forEach(fn => fn());
}
}</p><p>function reject(err) {
if (state === 'pending') {
state = 'rejected';
reason = err;
onRejectedCbs.forEach(fn => fn());
}
}</p><p>executor(resolve, reject);</p><p>this.then = function(onFulfilled, onRejected) {
return new MyPromise((resolveNext, rejectNext) => {
if (state === 'fulfilled') {
queueMicrotask(() => {
try {
const res = onFulfilled(value);
resolveNext(res);
} catch (e) {
rejectNext(e);
}
});
} else if (state === 'rejected') {
queueMicrotask(() => {
try {
const res = onRejected(reason);
resolveNext(res);
} catch (e) {
rejectNext(e);
}
});
} else {
onFulfilledCbs.push(() => {
queueMicrotask(() => {
try {
const res = onFulfilled(value);
resolveNext(res);
} catch (e) {
rejectNext(e);
}
});
});
onRejectedCbs.push(() => {
queueMicrotask(() => {
try {
const res = onRejected(reason);
resolveNext(res);
} catch (e) {
rejectNext(e);
}
});
});
}
});
};
}</p>用它跑一段链式调用:
new MyPromise(r => r(1))
.then(x => { console.log('A:', x); return x + 1; })
.then(x => { console.log('B:', x); return x * 2; })
.then(x => console.log('C:', x));
你会清晰看到 A→B→C 的顺序输出,且每个 .then() 的返回值自动成为下一个的输入——这就是链式调用的本质:**每个 .then() 构造并返回一个等待前一个结果的新 Promise,形成状态传递的管道**。
真正吃透的关键:返回值如何影响下一个 Promise 的状态
很多初学者卡在“为什么 return 一个普通值就往下传,return 一个 Promise 就要等它完成”。答案就在 .then() 内部对返回值的判断逻辑中:
- 如果 onFulfilled 返回的是 非 Promise 值(如数字、字符串、undefined),新 Promise 立即以该值 resolve
- 如果返回的是 Promise 或 thenable 对象(有 .then 方法),则新 Promise 进入“等待模式”,通过调用它的 .then 来接管其最终状态
- 这个机制叫 Promise Resolution Procedure(在 Promise/A+ 规范中有明确定义),手写时必须模拟它,才能让链式调用兼容原生行为
不复杂但容易忽略。










