使用 AbortController 取消正在运行的 Promise
2024-02-24 08:40:21
如何优雅地取消正在运行的 JavaScript Promise
在 JavaScript 中,Promise 是用来处理异步操作的强大工具。然而,它们缺乏一种内置机制来取消正在运行的任务。这就是 AbortController API 闪亮登场的时候,它提供了一种优雅的方式来终止进行中的 Promise。
AbortController:中止行动的控制者
想象 AbortController 是一个交通警察,当它挥舞着警棍时,所有正在进行的 Promise 都会立即停止。为了使用 AbortController,你需要:
- 创建 AbortController 对象: 就像创建一个新的交通警察一样,创建一个 AbortController 对象来管理你的 Promise。
- 将 AbortController 传递给 Promise: 当创建一个新的 Promise 时,将其链接到你的 AbortController 对象,就像警察指挥交通一样。
- 调用 abort(): 当你想取消 Promise 时,只需向 AbortController 对象发出 abort() 命令,它就会立即停止所有动作。
const controller = new AbortController();
const promise = new Promise((resolve, reject) => {
// 想象这是交通繁忙的十字路口,承诺在这里穿行。
setTimeout(() => {
resolve('完成');
}, 2000);
});
// 现在我们改变主意了,想取消这个繁忙的承诺。
controller.abort();
promise.then((result) => {
console.log('Promise 已完成,结果:', result); // 永远不会被调用,因为 Promise 已被取消。
}).catch((error) => {
console.log('Promise 已失败,错误信息:', error); // 可能会被调用,取决于 Promise 的具体实现。
});
AbortSignal:检查取消状态
AbortController 还提供了一个 AbortSignal 对象,它包含一个 aborted 属性,表示请求或任务是否已被取消。你可以使用它来检查你的 Promise 是否已被终止。
const controller = new AbortController();
const signal = controller.signal;
const promise = new Promise((resolve, reject) => {
// 想象这是交通繁忙的十字路口,承诺在这里穿行。
setTimeout(() => {
if (signal.aborted) {
reject('Promise 已被取消'); // 如果 Promise 已被取消,则拒绝。
} else {
resolve('完成'); // 如果 Promise 仍处于活动状态,则解决它。
}
}, 2000);
});
// 现在我们改变主意了,想取消这个繁忙的承诺。
controller.abort();
promise.then((result) => {
console.log('Promise 已完成,结果:', result); // 永远不会被调用,因为 Promise 已被取消。
}).catch((error) => {
console.log('Promise 已失败,错误信息:', error); // 会被调用,因为 Promise 已被明确取消。
});
AbortController 的妙用
AbortController 适用于各种异步操作,包括:
- Fetch 请求
- XMLHttpRequest 请求
- WebSocket 连接
- 自定义异步函数
常见问题解答
Q:为什么我需要使用 AbortController 而不是简单的 clearTimeout() 或 clearInterval()?
A:AbortController 提供了一种更通用的方法来取消各种类型的异步操作,而不仅仅是 setTimeout() 或 clearInterval()。
Q:AbortController 真的能取消任何 Promise 吗?
A:否,并非所有 Promise 都支持取消。具体取决于 Promise 的实现。
Q:AbortSignal 对象什么时候有用?
A:AbortSignal 对象可用于轮询 Promise 是否已被取消,即使在创建 Promise 时没有传递 AbortController。
Q:AbortController 会抛出异常吗?
A:否,AbortController 本身不会抛出异常。但是,如果尝试取消已解决或拒绝的 Promise,则 abort() 方法可能会抛出异常。
Q:AbortController 可以与异步/等待语法一起使用吗?
A:是的,AbortController 完全支持异步/等待语法。
结论
AbortController API 为优雅地取消正在运行的 JavaScript Promise 提供了一种强大且方便的方法。通过理解其功能,你可以增强你的代码,使其更加健壮和灵活。