Promise是如何实现then的链式调用的?
Promise 对象的 then
方法返回一个新的 Promise 对象,这是实现链式调用的关键。每一个 then
都会返回一个新的 Promise,而这个新的 Promise 的结果取决于 then
里面的回调函数的返回值。
以下是一个简化的 Promise 和 then
方法的实现,用于说明链式调用是如何工作的:
function Promise(executor) {
let self = this;
self.status = 'pending';
self.value = undefined;
self.reason = undefined;
self.onResolvedCallbacks = [];
self.onRejectedCallbacks = [];
function resolve(value) {
if (self.status === 'pending') {
self.status = 'resolved';
self.value = value;
self.onResolvedCallbacks.forEach(fn => fn());
}
}
function reject(reason) {
if (self.status === 'pending') {
self.status = 'rejected';
self.reason = reason;
self.onRejectedCallbacks.forEach(fn => fn());
}
}
try {
executor(resolve, reject);
} catch (err) {
reject(err);
}
}
Promise.prototype.then = function(onResolved, onRejected) {
let self = this;
return new Promise((resolve, reject) => {
function handledResolve(value) {
try {
let result = onResolved(value);
result instanceof Promise ? result.then(resolve, reject) : resolve(result);
} catch (err) {
reject(err);
}
}
function handledReject(reason) {
try {
let result = onRejected(reason);
result instanceof Promise ? result.then(resolve, reject) : reject(result);
} catch (err) {
reject(err);
}
}
switch (self.status) {
case 'pending':
self.onResolvedCallbacks.push(() => handledResolve(self.value));
self.onRejectedCallbacks.push(() => handledReject(self.reason));
break;
case 'resolved':
handledResolve(self.value);
break;
case 'rejected':
handledReject(self.reason);
break;
}
});
};
在这个简化的实现中,你可以看到 then
方法创建并返回了一个新的 Promise 对象。这个新的 Promise 对象的执行器函数会处理原始 Promise 对象的解决或拒绝,并根据 then
方法中提供的回调函数(onResolved
或 onRejected
)来决定新的 Promise 对象的状态。
如果原始 Promise 对象的状态是 'pending',那么新的 Promise 对象会将自己的回调函数添加到原始 Promise 对象的回调函数队列中,以便在原始 Promise 对象的状态改变时执行。如果原始 Promise 对象的状态已经是 'resolved' 或 'rejected',那么新的 Promise 对象会立即执行相应的回调函数。
这样,当你链式调用 then
方法时,你实际上是在创建一个 Promise 对象的链,每个对象都依赖于前一个对象的状态,并根据前一个对象的状态来决定自己的状态。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现