要实现一个 Promise,我们需要遵循 Promise/A+ 规范,这是一个开放的、无关实现的标准。我们先来看看基本的构造器和 .then 方法的实现:
function MyPromise(fn) {
let state = 'pending';
let value = null;
const callbacks = [];
this.then = function (onFulfilled) {
if (state === 'pending') {
callbacks.push(onFulfilled);
return this;
}
onFulfilled(value);
return this;
}
function resolve(newValue) {
value = newValue;
state = 'fulfilled';
setTimeout(() => {
callbacks.forEach(callback => callback(value));
}, 0);
}
fn(resolve);
}
这是最基础的 Promise 的实现,包括状态管理和 .then 方法的调用。在这个实现中,我们的 Promise 只能处理异步操作成功的情况(只实现了 resolve 函数),并且没有实现链式调用。
现在我们来看看怎么实现链式调用。要实现链式调用, .then 方法必须返回一个新的 Promise。这样我们就能创建一个新的 Promise,并且在当前 Promise 成功或失败后解析这个新的 Promise:
function MyPromise(fn) {
// ...
this.then = function (onFulfilled) {
return new MyPromise((resolve) => {
handle({
onFulfilled: onFulfilled || null,
resolve: resolve
});
});
};
function handle(callback) {
if (state === 'pending') {
callbacks.push(callback);
return;
}
if(!callback.onFulfilled) {
callback.resolve(value);
return;
}
const ret = callback.onFulfilled(value);
callback.resolve(ret);
}
// ...
function resolve(newValue) {
// ...
setTimeout(() => {
callbacks.forEach(handle);
}, 0);
}
// ...
fn(resolve);
}
在这个版本的实现中,我们增加了 handle 函数来处理回调,如果 Promise 还在 pending 状态,我们就把回调存到队列中,否则,我们就调用回调函数,并解析新的 Promise。
这只是实现 Promise 的基础部分。在实现一个完整的 Promise,需要处理许多复杂的情况,例如实现错误处理,处理在 .then 或 .catch 中返回的新 Promise,处理多次调用 .resolve 和 .reject 等。这个过程可能相当复杂,但它可以帮助你更深入地理解 Promise 的工作原理。
当然,让我来帮助你更深入地理解这段代码。这是一个基本的Promise的实现,我会逐行进行解释。
function MyPromise(fn) {
let state = 'pending'; // Promise的初始状态
let value = null; // Promise的值,这个值在Promise状态变为fulfilled时设置
const callbacks = []; // 这个数组保存.then()中的回调函数
MyPromise是我们自己的Promise实现。它的构造函数接受一个函数fn作为参数,这个函数有两个参数: resolve和reject,分别用于改变Promise的状态。我们还定义了**state 、 value和callbacks**三个变量,分别用于保存Promise的状态、值和回调函数。
this.then = function (onFulfilled) {
if (state === 'pending') {
callbacks.push(onFulfilled);
return this;
}
onFulfilled(value);
return this;
}
**.then()是Promise的一个方法,它接受一个回调函数onFulfilled作为参数。如果Promise的状态还是pending,那么这个回调函数会被保存到callbacks数组中;否则,回调函数将会被立即执行,并将Promise的值作为参数。 .then()**方法返回当前的Promise,以实现链式调用。
function resolve(newValue) {
value = newValue;
state = 'fulfilled';
setTimeout(() => {
callbacks.forEach(callback => callback(value));
}, 0);
}
**resolve函数是用来改变Promise的状态的。它接受一个新的值作为参数,将Promise的状态改为fulfilled,并设置Promise的值。然后,所有保存在callbacks数组中的回调函数将会被异步执行。我们使用setTimeout**来异步执行回调函数。
fn(resolve);
}
最后,我们调用**fn函数,并将resolve函数作为参数。这样,当fn函数执行完异步操作后,就可以通过调用resolve**函数来改变Promise的状态。
这就是Promise的基本工作原理。实际的Promise实现会更复杂,因为它还需要处理错误、实现**.catch()和.finally()**方法等。