【HTTP】取消已发送的请求

发布于:2025-06-25 ⋅ 阅读:(19) ⋅ 点赞:(0)

场景

        在页面中,可能会因为某些操作多次触发某个请求,如多次点击某按钮触发请求,实际上我们只需要最后一次请求的返回值,但是由于请求的耗时不一,请求未必会按发送的顺序返回,导致我们最终获取到的值 ≠ 最后一次发送请求的返回值

根据项目经验,目前一共尝试过两种方法

1. 设置请求的唯一 id 

2. 使用 axios 官方方法:AbortController

解决

1. 设置请求的唯一 id

        为每个请求设置一个唯一 id,每触发一次请求,id+1,多次触发请求后,取值时根据请求 id 值来对应取值。

使用示例如下:

// 设置请求id初始值为0
sessionStorage.setItem('id', JSON.stringify(0))
/**
 * 发送请求
 * @param data 请求参数
 */
function query(data) {
  loading.value = true
  // priceId加1,并存储在session里
  const priceId = JSON.parse(sessionStorage.getItem('id')) + 1
  sessionStorage.setItem('id', JSON.stringify(priceId))
  queryApi(data)
    .then(res => {
      // 根据session中的priceId, 取最后一次请求的返回值
      if (priceId === JSON.parse(sessionStorage.getItem('id'))) {
        // 处理业务逻辑
        const { resultData } = res
      }
    })
    .catch(err => {
      // 业务处理逻辑
    })
    .finally(() => {
      loading.value = false
    })
}

const url = '/query/abc'
function queryApi(paramsObj) {
  return httpInstance.post(url, paramsObj)
}

2. AbortController方法

        AbortController 是 axios 官方提供的取消请求的 api,使用时注意:

        1. 该 api 仅在 Axios 版本>=V0.22.0 时生效。

        2. Axios 版本<V0.22.0 时请使用 CancelToken

        3. 允许取消一个或多个正在进行的请求,但如果请求已经成功响应则不能取消。

官网文档链接:取消请求 | Axios中文文档 | Axios中文网

使用示例如下:

// 用于存储当前的 AbortController 实例
let currentController = null
/**
 * 发送请求
 * @param data 请求参数
 */
function query(data) {
  loading.value = true
  // 取消之前的请求
  if (currentController) {
    currentController.abort()
    currentController = null
  }
  const controller = new AbortController()
  currentController = controller //重置AbortController
  queryApi(data, controller.signal)
    .then(res => {
      const { resultData } = res
      // 业务处理逻辑.....
      loading.value = false
    })
    .catch(err => {
      if (err.name === 'CanceledError') {
        console.log('请求被取消', err.message)
      } else {
        console.error('请求失败', err)
        loading.value = false
      }
    })
}

const url = '/query/abc'
function queryApi(paramsObj, signal) {
  return httpInstance.post(url, paramsObj, {
    signal: signal
  })
}


网站公告

今日签到

点亮在社区的每一天
去签到