Axios 中断请求(AbortController、CancelToken)

1. 使用 AbortController

  • AbortController 是 Web API 的一部分,可以用来中止一个或多个 fetch 请求
  • 虽然 Axios 默认 不支持 直接使用 AbortController,但你可以通过传递 AbortController 的 signal 属性到 Axios请求 中来实现这一功能
  • 对于循环请求,你需要 为每个请求创建一个新的 AbortController 实例,并在合适的时机调用 abort 方法。
js 复制代码
const controller = new AbortController();
const { signal } = controller;

// 在你的请求中传递 signal
axios.get('/your-endpoint', { signal }).then(response => {
  // 处理响应
});

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

实例:如果有相同请求,先中断前一个

js 复制代码
const api = axios.create({
  baseURL: import.meta.env.VITE_APP_API_BASEURL,
  timeout: 1000 * 60,
})

const pendingMap = new Map() // abort 取消重复请求

function removePending(config: AxiosRequestConfig) {
  const key = `${config.method}:${config.url}:${JSON.stringify(filterNullUndefined(config.params || config.data))}`
  const abort = pendingMap.get(key)

  if (abort) {
    abort('cancel')
    pendingMap.delete(key)
  }
}

// axios实例拦截请求
api.interceptors.request.use(
  (config) => {
    // 如果有相同请求,先中断前一个
    removePending(config)
    const abortController = new AbortController()
    config.signal = abortController.signal
    pendingMap.set(
      `${config.method}:${config.url}:${JSON.stringify(filterNullUndefined(config.params || config.data))}`,
      () => abortController.abort('cancel'),
    )

    return config
  },
  (error) => {
    return Promise.reject(error)
  },
)

2. 使用 Axios 的 CancelToken

  • Axios 提供了 CancelToken 功能,可以用来取消请求。你可以创建一个 CancelToken 实例,并在请求中传递它
  • 对于循环请求,你同样需要 为每个请求创建一个新的 CancelToken 实例,并保存每个请求的 取消函数
js 复制代码
import axios from 'axios'
const CancelToken = axios.CancelToken
let cancel

axios.get('/your-endpoint', {
  cancelToken: new CancelToken((c) => {
    // 保存取消函数
    cancel = c
  }),
}).then((response) => {
  // 处理响应
})

// 当你需要取消请求时
cancel()

实例:离开页面前中断循环请求

js 复制代码
const cancel = reactive<any>({})

// 单个请求体,i为索引
function singleChunk(i: number) {
  const dId = dataId.value

  const p = () => {
    return new Promise((resolve, reject) => {
      chunkDownload({
        id: dId,
        chunk: i + 1,
      }, {
        cancelToken: new CancelToken((c) => {
          // 保存取消函数
          cancel[i + 1] = c
        }),
      }).then((info) => {
        // ....
      })
        .catch((err) => {
          reject(err)
        })
    })
  }

  return p
}

// ......................................

// 页面销毁前
onBeforeUnmount(() => {
  // 终止请求
  for (const key in cancel) {
    if (typeof (cancel[key] === 'function')) {
      cancel[key]()
    }
  }
})
相关推荐
子兮曰3 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰3 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万3 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝3 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋3 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁3 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
汉堡大王95273 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大3 天前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端
计算机魔术师3 天前
Meta Muse agent 接入 Shopify 的 Shop Pay 实现代理式购物
前端
沙蒿同学3 天前
我用 Go 搭了一条 AI Agent 流水线:从 1 张商品图到一整套淘宝详情页
前端·javascript·后端