返回 2. 定义
3. 定义
4. 定义
ES6 的 Promise 实现:亲手打造异步编程利器
前端
2023-10-03 06:40:29
在现代 Web 开发中,异步编程已经成为不可或缺的一部分。而 Promise,作为 JavaScript 中强大的异步编程工具,更是让开发者们如虎添翼。Promise 能够简化异步操作,让代码更具可读性和可维护性。但你知道 Promise 是如何实现的吗?
在本文中,我们将通过 65 行代码,手把手教你实现一个简化版的 ES6 Promise。通过这个过程,你将深入了解 Promise 的工作原理,以及如何使用它来编写更优美的异步代码。
理解 Promise 的基本原理
Promise 的核心思想很简单:它是一个对象,代表着一个异步操作的最终完成或失败的结果。你可以通过 then
方法来注册回调函数,以便在异步操作完成后执行。
Promise 有三种状态:
- Pending: 异步操作尚未完成。
- Fulfilled: 异步操作已成功完成。
- Rejected: 异步操作已失败。
实现我们的简化版 Promise
现在,让我们一步一步地实现我们的简化版 Promise。
1. 定义 Promise 构造函数
function Promise(executor) {
this.state = "pending";
this.result = undefined;
this.onFulfilledCallbacks = [];
this.onRejectedCallbacks = [];
const resolve = (result) => {
if (this.state !== "pending") return;
this.state = "fulfilled";
this.result = result;
this.onFulfilledCallbacks.forEach((callback) => callback(result));
};
const reject = (error) => {
if (this.state !== "pending") return;
this.state = "rejected";
this.result = error;
this.onRejectedCallbacks.forEach((callback) => callback(error));
};
executor(resolve, reject);
}
2. 定义 then
方法
Promise.prototype.then = function (onFulfilled, onRejected) {
return new Promise((resolve, reject) => {
if (this.state === "fulfilled") {
setTimeout(() => {
try {
const result = onFulfilled(this.result);
resolve(result);
} catch (error) {
reject(error);
}
}, 0);
} else if (this.state === "rejected") {
setTimeout(() => {
try {
const result = onRejected(this.result);
resolve(result);
} catch (error) {
reject(error);
}
}, 0);
} else {
this.onFulfilledCallbacks.push(() => {
setTimeout(() => {
try {
const result = onFulfilled(this.result);
resolve(result);
} catch (error) {
reject(error);
}
}, 0);
});
this.onRejectedCallbacks.push(() => {
setTimeout(() => {
try {
const result = onRejected(this.result);
resolve(result);
} catch (error) {
reject(error);
}
}, 0);
});
}
});
};
3. 定义 catch
方法
Promise.prototype.catch = function (onRejected) {
return this.then(null, onRejected);
};
4. 定义 resolve
和 reject
方法
const resolvePromise = (promise, x, resolve, reject) => {
if (promise === x) {
reject(new TypeError("Chaining cycle detected for promise"));
} else if (x instanceof Promise) {
x.then(
(result) => resolvePromise(promise, result, resolve, reject),
(error) => reject(error)
);
} else if (x !== null && (typeof x === "object" || typeof x === "function")) {
let then;
try {
then = x.then;
} catch (error) {
reject(error);
}
if (typeof then === "function") {
let called = false;
try {
then.call(
x,
(y) => {
if (called) return;
called = true;
resolvePromise(promise, y, resolve, reject);
},
(error) => {
if (called) return;
called = true;
reject(error);
}
);
} catch (error) {
if (called) return;
called = true;
reject(error);
}
} else {
resolve(x);
}
} else {
resolve(x);
}
};
const resolve = (value) => {
return new Promise((resolve, reject) => {
resolvePromise(this, value, resolve, reject);
});
};
const reject = (reason) => {
return new Promise((resolve, reject) => {
reject(reason);
});
};
5. 测试我们的简化版 Promise
现在,我们已经实现了我们的简化版 Promise,让我们来测试一下它是否正常工作。
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Hello, Promise!");
}, 1000);
});
promise
.then((result) => {
console.log(result); // 输出:"Hello, Promise!"
})
.catch((error) => {
console.log(error);
});
运行这段代码,你应该会在控制台看到 "Hello, Promise!"
。这表明我们的简化版 Promise 能够正常工作。
总结
通过这篇教程,我们一步一步地实现了 ES6 的 Promise。在这个过程中,我们深入了解了 Promise 的工作原理,以及如何使用它来编写更优美的异步代码。我希望这篇文章能够帮助你更好地理解和使用 Promise。