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 对象的链,每个对象都依赖于前一个对象的状态,并根据前一个对象的状态来决定自己的状态。