当前位置: 首页 > 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。

http://www.dtcms.com/a/91713.html

相关文章:

  • 数据结构 单链表 数组模仿链表
  • 【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 交错字符串
  • [FPGA基础学习]加法器、三八译码器及DE2-115基本使用方法和数码管显示
  • (C语言)动态分配的动态通讯录(静态通讯录Plus)(C语言小项目)
  • 关于跨域问题(本地前端访问服务器端接口跨域出错)
  • Notepad++ 替换 换行符 为 逗号
  • 关于服务器只能访问localhost:8111地址,局域网不能访问的问题
  • AWE直击:萤石RX30 Max的吸泡面战争,一场清洁技术的范式革命
  • 分布式服务的熔断和降级
  • Unity Shader 学习17:合批渲染
  • Spring Boot 连接 MySQL 配置参数详解
  • 维创智脑(WIC)项目观察:技术集成的理想模型与现实难题