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

什么是请求竞态?

  • 请求竞态(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
相关推荐
叩码以求索9 小时前
浅谈:算法萌新如何高效刷题应对面试(一)
算法·面试·职场和发展
用户0595401744610 小时前
LLM对话记忆测试踩坑实录:手工回归30分钟,自动化后2分钟发现3个隐藏Bug
前端·css
Ashley的成长之路11 小时前
前端性能优化实战手册·第2篇:资源加载策略全解
前端·性能优化·资源加载·http/3·性能优化实战·资源加载优化
浅水壁虎12 小时前
vue基础(第二章 )
前端·javascript·vue.js
界面开发小八哥12 小时前
界面控件DevExtreme v26.1新版亮点——支持Angular 22
前端·javascript·angular.js·devexpress·ui开发·devextreme
Getflare12 小时前
前端 + UI 设计 + AI:这不是三个工种,是一个新三角能力模型(附自检清单)
前端·人工智能·ui
oil欧哟12 小时前
我做了一个 Vibe Coding 术语学习站:VibeHub
前端·ai·agent·独立开发·vibe coding
审小匠OpenCPAi13 小时前
银行流水核查怎么自动化?单边匹配、双向勾稽与图聚类异常检测的工程对比
java·前端·人工智能·python·审计
Revolution6113 小时前
一个公共表格组件,是怎么一步步失控的
前端·前端工程化