js中AbortController请求中止的实现

 更新时间:2026年01月15日 11:04:44   作者:新节  
AbortController是JavaScript中用于中止Web请求的API,主要应用于fetch请求,也可用于其他浏览器API和第三方库,下面就来介绍一下AbortController请求中止的使用,感兴趣的可以了解一下

一、介绍

AbortControllerJavaScript 提供的一个强大工具,它允许开发者中止一个或多个 Web 请求。这个 API 最初是为了 fetch 请求设计的,但现在已经被许多其他浏览器 API 和第三方库所采用。

AbortController 的主要用途包括

  • 取消不再需要的 fetch 请求;
  • 清理长时间运行的操作;
  • 实现请求超时;
  • 处理组件卸载时的资源清理;

二、基本使用

2.1 创建 AbortController

const controller = new AbortController();
const signal = controller.signal;

2.2 与 fetch 结合使用

const controller = new AbortController();
const signal = controller.signal;

fetch("https://api.example.com/data", { signal })
  .then((response) => response.json())
  .then((data) => console.log(data))
  .catch((err) => {
    if (err.name === "AbortError") {
      console.log("请求被中止");
    } else {
      console.error("请求错误:", err);
    }
  });

// 在需要时中止请求
controller.abort();

三、常用场景

3.1 用户触发的取消

const controller = new AbortController();
const fetchButton = document.getElementById("fetch-button");
const cancelButton = document.getElementById("cancel-button");

fetchButton.addEventListener("click", () => {
  fetch("https://api.example.com/data", { signal: controller.signal }).then(/* ... */).catch(/* ... */);
});

cancelButton.addEventListener("click", () => {
  controller.abort();
});

3.2 请求超时

function fetchWithTimeout(url, options, timeout = 5000) {
  const controller = new AbortController();
  const signal = controller.signal;

  // 设置超时
  const timeoutId = setTimeout(() => controller.abort(), timeout);

  return fetch(url, { ...options, signal }).finally(() => clearTimeout(timeoutId));
}

fetchWithTimeout("https://api.example.com/data", {}, 3000)
  .then(/* ... */)
  .catch((err) => {
    if (err.name === "AbortError") {
      console.log("请求超时");
    }
  });

3.3 React 组件卸载时取消请求

import { useEffect, useState } from "react";

function DataFetcher() {
  const [data, setData] = useState(null);

  useEffect(() => {
    const controller = new AbortController();

    fetch("https://api.example.com/data", { signal: controller.signal })
      .then((response) => response.json())
      .then(setData)
      .catch((err) => {
        if (err.name !== "AbortError") {
          console.error("获取数据失败:", err);
        }
      });

    return () => controller.abort();
  }, []);

  return <div>{data ? JSON.stringify(data) : "加载中..."}</div>;
}

3.4 并行请求的统一取消

const controller = new AbortController();
const signal = controller.signal;

const requests = [fetch("/api/data1", { signal }), fetch("/api/data2", { signal }), fetch("/api/data3", { signal })];

Promise.all(requests)
  .then(/* 处理所有响应 */)
  .catch((err) => {
    if (err.name === "AbortError") {
      console.log("所有请求已被取消");
    }
  });

// 取消所有请求
controller.abort();

四、高级细节

4.1 信号状态

signal.aborted 属性可以检查信号是否已被中止:

const controller = new AbortController();
console.log(controller.signal.aborted); // false

controller.abort();
console.log(controller.signal.aborted); // true

4.2 事件监听

可以监听 abort 事件:

const controller = new AbortController();

controller.signal.addEventListener("abort", () => {
  console.log("请求被中止");
});

controller.abort();

4.3 重用与限制

一个 AbortController 只能中止一次,之后就不能再使用了:

const controller = new AbortController();
controller.abort();
controller.abort(); // 第二次调用不会有任何效果

如果需要多次中止操作,需要创建新的 AbortController 实例。

4.4 与其他 API 集成

除了 fetch,AbortController 还可以用于其他 API:

// Web APIs
const videoStream = await navigator.mediaDevices.getUserMedia({
  video: true,
  signal: controller.signal
});

// Axios
const source = axios.CancelToken.source();
axios.get("/api/data", {
  cancelToken: source.token
});
source.cancel();

4.5 自定义中止逻辑

你可以基于 AbortSignal 实现自己的可中止操作:

function doTask(signal) {
  return new Promise((resolve, reject) => {
    const timer = setTimeout(() => resolve("任务完成"), 5000);

    signal.addEventListener("abort", () => {
      clearTimeout(timer);
      reject(new DOMException("任务被中止", "AbortError"));
    });

    if (signal.aborted) {
      clearTimeout(timer);
      reject(new DOMException("任务被中止", "AbortError"));
    }
  });
}

const controller = new AbortController();
doTask(controller.signal)
  .then(console.log)
  .catch((err) => {
    if (err.name === "AbortError") {
      console.log("任务被中止");
    }
  });

// 中止任务
controller.abort();

到此这篇关于js中AbortController请求中止的实现的文章就介绍到这了,更多相关js AbortController请求中止内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • JS时间戳与日期格式互相转换的简单方法示例

    JS时间戳与日期格式互相转换的简单方法示例

    这篇文章主要给大家介绍了关于JS时间戳与日期格式互相转换的简单方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • 详解webpack模块加载器兼打包工具

    详解webpack模块加载器兼打包工具

    这篇文章主要介绍了webpack模块加载器兼打包工具,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-09-09
  • 小程序分页实践之编写可复用分页组件

    小程序分页实践之编写可复用分页组件

    这篇文章主要介绍了小程序分页实践之编写可复用分页组件,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-07-07
  • JavaScript入门教程之引用类型

    JavaScript入门教程之引用类型

    引用类型是一种数据结构,用于将数据和功能组织在一起。这篇文章主要介绍了JavaScript入门教程之引用类型的相关资料,需要的朋友一起学习吧
    2016-05-05
  • js实现适合新闻类图片的轮播效果

    js实现适合新闻类图片的轮播效果

    本文主要分享了js实现适合新闻类图片轮播效果的示例代码,具有一定的参考价值,下面跟着小编一起来看下吧
    2017-02-02
  • js获取USB扫码枪数据的方法

    js获取USB扫码枪数据的方法

    这篇文章主要为大家详细介绍了js获取USB扫码枪数据的方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-09-09
  • 微信小程序之圆形进度条实现思路

    微信小程序之圆形进度条实现思路

    这篇文章主要介绍了微信小程序之圆形进度条实现思路,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2018-02-02
  • 全解跨域请求问题处理方法及分析

    全解跨域请求问题处理方法及分析

    这篇文章主要为大家介绍了全解跨域请求问题处理方法及分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪<BR>
    2023-07-07
  • JS实现页面载入时随机显示图片效果

    JS实现页面载入时随机显示图片效果

    这篇文章主要介绍了JS实现页面载入时随机显示图片效果,涉及javascript基于随机数与数组的页面元素动态修改相关操作技巧,需要的朋友可以参考下
    2016-09-09
  • 获取当前网页document.url location.href区别总结

    获取当前网页document.url location.href区别总结

    请教:document.URL和window.location.href区别
    2008-05-05

最新评论