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

什么是请求竞态?

  • 请求竞态(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
相关推荐
冴羽12 小时前
今日苹果 App Store 前端源码泄露,赶紧 fork 一份看看
前端·javascript·typescript
蒜香拿铁12 小时前
Angular【router路由】
前端·javascript·angular.js
卡卡酷卡BUG12 小时前
Java 后端面试干货:四大核心模块高频考点深度解析
java·开发语言·面试
brzhang12 小时前
读懂 MiniMax Agent 的设计逻辑,然后我复刻了一个MiniMax Agent
前端·后端·架构
西洼工作室12 小时前
高效管理搜索历史:Vue持久化实践
前端·javascript·vue.js
广州华水科技12 小时前
北斗形变监测传感器在水库安全中的应用及技术优势分析
前端
开发者如是说13 小时前
Compose 开发桌面程序的一些问题
前端·架构
旺代13 小时前
Token 存储与安全防护
前端
洋不写bug14 小时前
html实现简历信息填写界面
前端·html
三十_A14 小时前
【无标题】
前端·后端·node.js