首页 > web前端 > js教程 > 你真的了解AbortController吗?

你真的了解AbortController吗?

Patricia Arquette
发布: 2025-01-17 02:38:09
原创
708 人浏览过

你真的了解AbortController吗?

许多开发人员可能认为他们了解 AbortController,但它的功能远远超出了基础知识。从取消获取请求到管理事件监听器和 React hooks。

你真的知道AbortController有多强大吗?让我们看看:

使用 AbortController 取消获取请求

将 AbortController 与 fetch 结合使用,当然是最常见的用法。

以下示例演示了如何使用 AbortController 创建可取消的获取请求:

fetchButton.onclick = async () => {
  const controller = new AbortController();
  // Add a cancel button
  abortButton.onclick = () => controller.abort();
  try {
    const response = await fetch('/json', { signal: controller.signal });
    const data = await response.json();
    // Perform business logic here
  } catch (error) {
    const isUserAbort = error.name === 'AbortError';
    // AbortError is thrown when the request is canceled using AbortController
  }
};
登录后复制
登录后复制

上面的示例展示了在引入 AbortController 之前不可能实现的功能:以编程方式取消网络请求的能力。取消后,浏览器将停止获取,从而节省网络带宽。重要的是,取消不必由用户发起。

controller.signal 提供了一个 AbortSignal 对象,可以与 fetch 等异步操作进行通信,并允许取消它们。

要将多个信号合并为一个信号,可以使用 AbortSignal.any()。方法如下:

try {
  const controller = new AbortController();
  const timeoutSignal = AbortSignal.timeout(5000);
  const response = await fetch(url, {
    // Abort fetch if any of the signals are triggered
    signal: AbortSignal.any([controller.signal, timeoutSignal]),
  });
  const data = await response.json();
} catch (error) {
  if (error.name === 'AbortError') {
    // Notify the user of cancellation
  } else if (error.name === 'TimeoutError') {
    // Notify the user of timeout
  } else {
    // Handle other errors, like network issues
    console.error(`Type: ${error.name}, Message: ${error.message}`);
  }
}
登录后复制
登录后复制

AbortController 和 AbortSignal 之间的区别

  • AbortController:用于通过controller.abort()显式取消关联信号。
  • AbortSignal:代表信号对象;它不能直接取消任何内容,但会传达其中止状态。

对于 AbortSignal,您可以:

  • 使用signal.aborted检查是否中止。
  • 监听中止事件:
if (signal.aborted) {
}
signal.addEventListener('abort', () => {});
登录后复制
登录后复制

当使用 AbortController 取消请求时,服务器将不会处理该请求或发送响应,从而通过减少并发连接来节省带宽并提高客户端性能。

AbortController 的常见用例

取消 WebSocket 连接

WebSocket 等较旧的 API 本身并不支持 AbortSignal。相反,您可以像这样实现取消:

function abortableSocket(url, signal) {
  const socket = new WebSocket(url);
  if (signal.aborted) {
    socket.close();
    // Abort immediately if already canceled
  }
  signal.addEventListener('abort', () => socket.close());
  return socket;
}
登录后复制

注意:如果AbortSignal已经中止,则不会触发中止事件,因此需要提前检查并处理这种情况。

删除事件监听器

传统上,删除事件侦听器需要传递完全相同的函数引用:

window.addEventListener('resize', () => doSomething());
window.removeEventListener('resize', () => doSomething()); // This won’t work
登录后复制

使用 AbortController,这变得更容易:

const controller = new AbortController();
const { signal } = controller;
window.addEventListener('resize', () => doSomething(), { signal });
// Remove the event listener by calling abort()
controller.abort();
登录后复制

对于较旧的浏览器,请考虑添加一个polyfill来支持AbortController。

在 React Hook 中管理异步任务

在 React 中,如果组件在上一个异步任务完成之前更新,效果可能会无意中并行运行:

function FooComponent({ something }) {
  useEffect(async () => {
    const data = await fetch(url + something);
    // Handle the data
  }, [something]);
  return ...>;
}
登录后复制

为了避免此类问题,请使用 AbortController 取消之前的任务:

fetchButton.onclick = async () => {
  const controller = new AbortController();
  // Add a cancel button
  abortButton.onclick = () => controller.abort();
  try {
    const response = await fetch('/json', { signal: controller.signal });
    const data = await response.json();
    // Perform business logic here
  } catch (error) {
    const isUserAbort = error.name === 'AbortError';
    // AbortError is thrown when the request is canceled using AbortController
  }
};
登录后复制
登录后复制

在 Node.js 中使用 AbortController

现代 Node.js 包含与 AbortController 兼容的 setTimeout 实现:

try {
  const controller = new AbortController();
  const timeoutSignal = AbortSignal.timeout(5000);
  const response = await fetch(url, {
    // Abort fetch if any of the signals are triggered
    signal: AbortSignal.any([controller.signal, timeoutSignal]),
  });
  const data = await response.json();
} catch (error) {
  if (error.name === 'AbortError') {
    // Notify the user of cancellation
  } else if (error.name === 'TimeoutError') {
    // Notify the user of timeout
  } else {
    // Handle other errors, like network issues
    console.error(`Type: ${error.name}, Message: ${error.message}`);
  }
}
登录后复制
登录后复制

与浏览器 setTimeout 不同,此实现不接受回调;相反,使用 .then() 或 wait.

用于高级调度的任务控制器

浏览器正在转向使用 Scheduler.postTask() 来确定任务优先级,其中 TaskController 扩展了 AbortController。您可以使用它来取消任务并动态调整其优先级:

if (signal.aborted) {
}
signal.addEventListener('abort', () => {});
登录后复制
登录后复制

如果不需要优先级控制,可以直接使用AbortController来代替。

结论

AbortController 是现代 JavaScript 开发中的重要工具,提供了管理和取消异步任务的标准化方法。

它与浏览器和 Node.js 环境的集成凸显了它的多功能性和重要性。

如果您不了解 AbortController,现在是时候拥抱它的全部功能并使其成为异步编程工具包的基石了。


我们是 你真的了解AbortController吗?,是将 Node.js 项目部署到云端的首选。

你真的了解AbortController吗?

你真的了解AbortController吗? 是用于 Web 托管、异步任务和 Redis 的下一代无服务器平台:

多语言支持

  • 使用 Node.js、Python、Go 或 Rust 进行开发。

免费部署无限个项目

  • 只需支付使用费用——无请求,不收费。

无与伦比的成本效率

  • 即用即付,无闲置费用。
  • 示例:25 美元支持 694 万个请求,平均响应时间为 60 毫秒。

简化的开发者体验

  • 直观的用户界面,轻松设置。
  • 完全自动化的 CI/CD 管道和 GitOps 集成。
  • 实时指标和日志记录以获取可行的见解。

轻松的可扩展性和高性能

  • 自动扩展,轻松处理高并发。
  • 零运营开销 - 只需专注于构建。

在文档中探索更多内容!

Try 你真的了解AbortController吗?

在 X 上关注我们:@你真的了解AbortController吗?HQ


阅读我们的博客

以上是你真的了解AbortController吗?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:dev.to
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板