当前位置: 首页 > news >正文

#vue中解决异步请求的竞态

// composables/useFetchWithoutRace.js
import { ref } from 'vue';
import axios from 'axios';

// 定义一个可复用的 Composition 函数,处理带有竞态控制的异步请求
export function useFetchWithoutRace() {
  // 定义响应式变量 `latestRequestId`,用于追踪最新请求的标识
  const latestRequestId = ref(null);

  // 定义异步请求函数,接收 AJAX 配置对象,返回请求结果
  const fetchWithoutRace = async (ajaxConfig) => {
    // 生成当前请求的唯一标识,使用时间戳确保每次请求都有不同的 ID
    const requestId = Date.now();
    
    // 更新 `latestRequestId`,标记这个请求为最新的
    latestRequestId.value = requestId;

    try {
      // 使用传入的 ajaxConfig 发送请求,axios 会根据配置自动处理 method、url、params 等
      const response = await axios(ajaxConfig);
      
      // 检查当前请求的 ID 是否仍然是最新的
      if (requestId === latestRequestId.value) {
        // 如果是最新的请求,直接返回响应数据
        return response.data;
      }
      // 如果不是最新的请求,返回 null 或抛出特定标识,避免使用旧数据
      return null;
    } catch (error) {
      // 捕获请求中的错误,抛出以便调用者处理
      console.error('Fetch error:', error);
      throw error;
    }
  };

  // 返回 `fetchWithoutRace` 方法,供组件调用
  return {
    fetchWithoutRace, // 请求方法,返回 Promise,包含结果或 null
  };
}

在组件中使用

// 组件代码
<script>
import { ref } from 'vue';
import { useFetchWithoutRace } from '@/composables/useFetchWithoutRace';

export default {
  setup() {
    // 调用 useFetchWithoutRace,获取 fetchWithoutRace 方法
    const { fetchWithoutRace } = useFetchWithoutRace();
    
    // 定义响应式变量,用于存储结果
    const result = ref(null);

    // 定义处理输入的方法,构造 AJAX 配置对象并调用 fetchWithoutRace
    const handleInput = async (value) => {
      // 创建 AJAX 配置对象
      const ajaxConfig = {
        url: '/api/data',       // 请求的 API 地址
        method: 'get',         // 请求方法,默认为 GET
        params: { q: value },  // 查询参数,传递输入框的值
      };
      
      try {
        // 调用 fetchWithoutRace,等待结果
        const data = await fetchWithoutRace(ajaxConfig);
        // 如果是最新请求,data 会有值;否则为 null
        if (data !== null) {
          result.value = data;
        }
      } catch (error) {
        // 处理请求错误
        console.log('处理错误:', error);
      }
    };

    // 返回给模板使用的变量和方法
    return {
      result,      // 请求结果,用于显示
      handleInput, // 输入处理方法,绑定到输入框
    };
  },
};
</script>

<template>
  <div>
    <!-- 输入框,每次输入时调用 handleInput,传入输入值 -->
    <input @input="handleInput($event.target.value)" placeholder="输入查询" />
    <!-- 显示请求结果,result 是响应式的,数据更新时自动刷新 -->
    <p>结果: {{ result }}</p>
  </div>
</template>

让调用者自己管理结果, fetchWithoutRace 直接返回请求数据。

fetchWithoutRace 返回一个 Promise,成功时解析为:
如果是最新请求,返回 response.data。
如果不是最新请求,返回 null。
失败时抛出错误,交给调用者处理。

竞态控制:
依然通过 requestId 和 latestRequestId 判断,只有最新请求的结果会被返回。
非最新请求返回 null,避免旧数据干扰。

调用者控制结果:
组件中用 await fetchWithoutRace(ajaxConfig) 获取结果,然后手动赋值给 result。

相关文章:

  • 数据结构 单链表 数组模仿链表
  • 【Java/数据结构】二叉树(BinaryTree)
  • ipconfig、ping、ipconfig/all 4个常用 **Windows终端(CMD)命令** 的详细解释
  • vscode 通过Remote-ssh远程连接服务器报错 could not establish connection to ubuntu
  • 基于ssm人脸识别的网络相册管理系统(源码+lw+部署文档+讲解),源码可白嫖!
  • 2-2 MATLAB鮣鱼优化算法ROA优化CNN超参数回归预测
  • 【git】认识git的本地仓库
  • jeecgboot vue 分片上传 minio
  • AOA与TOA混合定位,MATLAB例程,自适应基站数量,三维空间下的运动轨迹,滤波使用EKF
  • Apache Shiro 统一化实现多端登录(PC端移动端)
  • canvas.toDataURL返回 Base64 编码黑色图片的检测方法
  • cs231n-图像分类:kNN与线性分类器
  • 【遥感小目标数据集】【AI-TOD】Tiny Object Detection in Aerial Images
  • Java多线程与JConsole实践:从线程状态到性能优化!!!
  • LeetCode Hot100 刷题笔记(4)—— 二叉树、图论
  • PyTorch实现Transformer模型
  • 输出输入练习
  • 《数字图像处理》第四章 频率域滤波简要学习笔记以及频率域滤波与空间域滤波的区别
  • 构建稳健的机器学习系统:应对数据偏移挑战
  • Leetcode 交错字符串
  • 意德首脑会谈,梅洛尼警告欧盟绿色政策面临“工业荒漠化”
  • 上海市第二十届青少年科技节启动:为期半年,推出百余项活动
  • 有关“普泽会”,俄官方表示:有可能
  • 特朗普称即将与伊朗达成核协议,外交部:中方愿继续发挥建设性作用
  • 中方是否计划解除或调整稀土出口管制?外交部回应
  • “多规合一”改革7年成效如何?自然资源部总规划师亮成绩单