返回
剖析 Promise 源码,五分钟教你实现异步编程利器
前端
2023-10-30 02:32:28
掌握 Promise,即可轻松实现异步编程,告别回调函数的繁杂,尽享代码简洁之美。
Promise 是 JavaScript 中的异步编程利器,它允许我们轻松处理异步操作,让代码更具可读性和可维护性。实现 Promise 并不难,只需五分钟,就能彻底掌握其工作原理。
首先,我们来拆解 Promise 的基本结构:
class Promise {
constructor(executor) {
this.state = "pending";
this.result = undefined;
this.onResolveCallbacks = [];
this.onRejectCallbacks = [];
const resolve = (value) => {
if (this.state === "pending") {
this.state = "fulfilled";
this.result = value;
this.onResolveCallbacks.forEach((callback) => callback(value));
}
};
const reject = (error) => {
if (this.state === "pending") {
this.state = "rejected";
this.result = error;
this.onRejectCallbacks.forEach((callback) => callback(error));
}
};
executor(resolve, reject);
}
then(onResolve, onReject) {
return new Promise((resolve, reject) => {
if (this.state === "fulfilled") {
onResolve(this.result);
} else if (this.state === "rejected") {
onReject(this.result);
} else {
this.onResolveCallbacks.push(() => {
onResolve(this.result);
});
this.onRejectCallbacks.push(() => {
onReject(this.result);
});
}
});
}
catch(onReject) {
return this.then(null, onReject);
}
finally(onFinally) {
return this.then(
(result) => {
onFinally();
return result;
},
(error) => {
onFinally();
throw error;
}
);
}
}
Promise 的核心在于 state
、result
和三个回调函数数组:onResolveCallbacks
、onRejectCallbacks
和 finallyCallbacks
。
state
属性表示 Promise 的状态,可以是 "pending"、"fulfilled" 或 "rejected"。
result
属性存储 Promise 的结果,当 Promise 被成功解析时,该属性将存储解析值;当 Promise 被拒绝时,该属性将存储拒绝原因。
onResolveCallbacks
、onRejectCallbacks
和 finallyCallbacks
数组分别存储当 Promise 被解析、被拒绝或执行 finally 时要调用的回调函数。
Promise 提供了 then()
、catch()
和 finally()
三个方法:
then()
方法接受两个参数,第一个参数是当 Promise 被解析时要调用的回调函数,第二个参数是当 Promise 被拒绝时要调用的回调函数。catch()
方法接受一个参数,是当 Promise 被拒绝时要调用的回调函数。finally()
方法接受一个参数,是当 Promise 被解析或被拒绝时都要调用的回调函数。
现在,让我们一步一步实现属于自己的 Promise:
function myPromise(executor) {
let state = "pending";
let result;
const callbacks = [];
const resolve = (value) => {
if (state === "pending") {
state = "fulfilled";
result = value;
callbacks.forEach((callback) => callback(value));
}
};
const reject = (error) => {
if (state === "pending") {
state = "rejected";
result = error;
callbacks.forEach((callback) => callback(error));
}
};
executor(resolve, reject);
return {
then(callback) {
return new myPromise((resolve, reject) => {
if (state === "fulfilled") {
resolve(callback(result));
} else if (state === "rejected") {
reject(callback(result));
} else {
callbacks.push(() => {
resolve(callback(result));
});
}
});
},
catch(callback) {
return new myPromise((resolve, reject) => {
if (state === "rejected") {
resolve(callback(result));
} else if (state === "fulfilled") {
reject(callback(result));
} else {
callbacks.push(() => {
resolve(callback(result));
});
}
});
},
finally(callback) {
return new myPromise((resolve, reject) => {
if (state === "fulfilled") {
resolve(callback());
} else if (state === "rejected") {
reject(callback());
} else {
callbacks.push(() => {
resolve(callback());
});
}
});
}
};
}
这个简单的实现足以让我们掌握 Promise 的基本原理。我们可以使用它来实现一些实用的功能,例如:
const promise = new myPromise((resolve, reject) => {
setTimeout(() => {
resolve("Hello, world!");
}, 1000);
});
promise.then((result) => {
console.log(result); // "Hello, world!"
});
这个代码创建一个 Promise,并在 1 秒后解析它。然后,我们使用 then()
方法来处理解析结果。
这就是 Promise 的基本原理。只要掌握了这些基础知识,我们就可以轻松实现异步编程,让我们的代码更具可读性和可维护性。