通过取消请求解决请求竞态问题

什么是请求竞态?

  • 请求竞态(Race Condition)是指在前端开发中,当多个异步请求(如 AJAX、Fetch 或 Axios 请求)同时发起时,由于网络延迟或服务器响应时间不同,导致后发起的请求可能比先发起的请求更早返回,从而使得最终显示的数据不符合预期顺序。
  • 简而言之就是:接口的请求顺序不一定等于接口的返回顺序。
  • 例如下图

当我快速点击按钮1、按钮2时,由于接口的响应速度不一定一样,因此导致页面上显示的是page1,这就是一个典型的请求竞态

如何解决?

解决这个问题,我这里提供两种方案:

  1. 前端每次发送请求时都带一个requestId给后端,后端返回结果时也把这个requestId返回过来,接口响应数据后,请端通过最后一次都requestId来找到后端最新的接口返回的数据,这种方案有个缺点就是需要去动服务端。
  2. 纯前端利用abort来取消请求,每次发送请求时先判断上一次是不是请求过相同的接口了,如果有就取消上一次的请求。

这里简单提一下一些ajax取消请求的方法

  1. xhr利用abort()取消

2.fetch利用AbortController

由于现在的项目大多都是用axios,因此我这里讲axios如何取消请求

js 复制代码
import axios from 'axios'

const requestMap = new Map()
const pushRequest = (config) => {
  const { url2, method } = config
  const uniq = `${url2}_${method}` // 自行调整
  // 当我们每次发起请求时,先去map中找是否有相同的请求,如果有则讲上一次的请求取消掉
  if (!requestMap.has(uniq)) {
    const controller = new AbortController()
    config.signal = controller.signal
    requestMap.set(uniq, controller)
  } else {
    const controller = requestMap.get(uniq)
    controller.abort() // 取消请求
    requestMap.delete(uniq) // 删除controller
  }
}
const removeRequest = (config) => {
  const { url2, method } = config
  const uniq = `${url2}_${method}`
  if (requestMap.has(uniq)) {
    requestMap.delete(uniq)
  }
}
const request = axios.create({
  baseURL: 'http://localhost:12306/',
})
try {
  request.interceptors.request.use(
    (config) => {
      pushRequest(config)
      console.log('map', requestMap)
      console.log('Request Interceptor', config)
      return config
    },
    (err) => {
      console.log('Request Error', err)
      return Promise.reject(err)
    },
  )
} catch (error) {
  console.log('Request Error', error)
}
request.interceptors.response.use(
  (response) => {
    removeRequest(response.config)
    console.log('Response Interceptor', requestMap)
    return response
  },
  (err) => {
    return Promise.reject(err)
  },
)
export default request
相关推荐
mayaairi31 分钟前
Vue2 事件绑定完全指南:从入门到原理
前端·javascript·vue.js
不正经学生4 小时前
C语言预处理详解:编译器真正动手之前的那些事
c语言·开发语言·算法·面试·bug
ℋᙚᵐⁱᒻᵉ鲸落6 小时前
移动端滑动手势冲突:overflow: auto导致外层横向滑动失效
前端·javascript·css·vue.js·html
默_笙8 小时前
🎃 前端学了 Next.js,后端该学啥?NestJS 就是 Node 版的蜜雪冰城
前端·javascript
怕浪猫8 小时前
AI Agent 的安全围栏:DeepSeek Harness 沙箱隔离策略全解析
面试·agent·产品经理
前端snow9 小时前
ai agent --- 实现 openclaw 定时间效果
前端
码云之上9 小时前
换模型之后,Chatbot 为什么要自己做 compact?
前端·agent·前端工程化
星栈9 小时前
自定义 UI-UX-Pro-Max 的 CSV 知识库,把 AI 生成的后台拉回行业该有的样子
前端·agent·weui
研☆香9 小时前
简单的图片上传 删除 预览
前端
ITresearchGuest9 小时前
我用 AI 一小时写了一个世界杯数据可视化平台|前端 VibeCoding 初体验
前端·人工智能·信息可视化