解析NaiveUiAdmin的vue开源项目(三)

解析NaiveUiAdmin的vue开源项目(二)-CSDN博客

咱们接着学习把

src/utils/http/axios/axiosCancel.ts

import axios, { AxiosRequestConfig, Canceler } from 'axios';
import qs from 'qs';

import { isFunction } from '@/utils/is/index';

// 声明一个 Map 用于存储每个请求的标识 和 取消函数
let pendingMap = new Map<string, Canceler>();

export const getPendingUrl = (config: AxiosRequestConfig) =>
  [config.method, config.url, qs.stringify(config.data), qs.stringify(config.params)].join('&');

export class AxiosCanceler {
  /**
   * 添加请求
   * @param {Object} config
   */
  addPending(config: AxiosRequestConfig) {
    this.removePending(config);
    const url = getPendingUrl(config);
    config.cancelToken =
      config.cancelToken ||
      new axios.CancelToken((cancel) => {
        if (!pendingMap.has(url)) {
          // 如果 pending 中不存在当前请求,则添加进去
          pendingMap.set(url, cancel);
        }
      });
  }

  /**
   * @description: 清空所有pending
   */
  removeAllPending() {
    pendingMap.forEach((cancel) => {
      cancel && isFunction(cancel) && cancel();
    });
    pendingMap.clear();
  }

  /**
   * 移除请求
   * @param {Object} config
   */
  removePending(config: AxiosRequestConfig) {
    const url = getPendingUrl(config);

    if (pendingMap.has(url)) {
      // 如果在 pending 中存在当前请求标识,需要取消当前请求,并且移除
      const cancel = pendingMap.get(url);
      cancel && cancel(url);
      pendingMap.delete(url);
    }
  }

  /**
   * @description: 重置
   */
  reset(): void {
    pendingMap = new Map<string, Canceler>();
  }
}

以下是对这段代码的分析:

功能概述

这段代码主要用于管理 Axios 请求的取消操作,以避免重复请求和资源浪费。它通过使用 axios 库进行网络请求,并借助 qs 库来处理查询参数的序列化。同时,引入了一个自定义的工具函数 isFunction 用于判断一个值是否为函数。

主要组成部分

  1. pendingMap:一个 Map 对象,用于存储每个请求的唯一标识和对应的取消函数。pending未决的

  2. getPendingUrl 函数:接收一个 AxiosRequestConfig 对象作为参数,通过拼接请求方法、URL、请求数据(如果有)和查询参数(如果有)来生成一个唯一的请求标识字符串。

  3. AxiosCanceler 类

    • addPending 方法:在发送请求前调用此方法,它首先尝试移除可能存在的重复请求,然后为当前请求创建一个取消令牌(cancelToken),并将其与请求的唯一标识一起存储在 pendingMap 中。如果 pendingMap 中不存在当前请求的标识,则将取消函数添加到 pendingMap 中。
    • removeAllPending 方法:用于取消所有挂起的请求。它遍历 pendingMap,调用每个取消函数,并清空 pendingMap
    • removePending 方法:在请求完成或取消时调用,它根据请求的配置生成唯一标识,检查 pendingMap 中是否存在该标识。如果存在,则调用对应的取消函数并从 pendingMap 中删除该请求的标识和取消函数。
    • reset 方法:用于重置 pendingMap,将其重新初始化为一个新的 Map 对象。

以下是对上述代码逻辑的详细解释

整体目的

这段代码的主要目的是管理使用 axios 库发送的 HTTP 请求,通过跟踪请求的状态并提供取消特定请求或所有请求的功能,以避免不必要的网络请求和资源浪费。

具体逻辑步骤

  1. 导入模块和工具函数

    • 引入 axios 库,以便发送 HTTP 请求。同时,导入了 AxiosRequestConfig 和 Canceler 类型,分别用于配置请求和表示取消函数。
    • 引入 qs 库用于序列化请求参数,以便生成唯一的请求标识。
    • 引入自定义的 isFunction 工具函数,用于判断一个值是否为函数。
  2. 定义请求标识存储容器

    • 创建一个 Map 对象 pendingMap,用于存储请求的唯一标识(字符串类型)和对应的取消函数(Canceler 类型)。
  3. 生成请求唯一标识函数

    • getPendingUrl 函数接收一个 AxiosRequestConfig 对象作为参数,通过拼接请求的方法、URL、请求数据(如果有,经过序列化)和查询参数(如果有,经过序列化),生成一个唯一的请求标识字符串。这个唯一标识将用于区分不同的请求,并在 pendingMap 中进行存储和管理。
  4. 定义请求取消管理类 AxiosCanceler

    • addPending 方法:
      • 接收一个 AxiosRequestConfig 对象,表示要添加的请求配置。
      • 首先调用 removePending(config),可能是为了确保在添加新请求之前,先移除可能存在的重复请求。
      • 然后通过 getPendingUrl(config) 生成请求的唯一标识 url
      • 检查请求配置中是否已经存在取消令牌(cancelToken)。如果不存在,则创建一个新的取消令牌,并将其与生成的唯一标识关联起来。如果 pendingMap 中不存在当前请求的标识,则将取消函数添加到 pendingMap 中,以便后续可以通过这个唯一标识来取消该请求。
    • removeAllPending 方法:
      • 遍历 pendingMap 中的每个取消函数。
      • 对于每个取消函数,如果它存在并且是一个函数,则调用该取消函数来取消对应的请求。
      • 最后清空 pendingMap,以便重新开始管理新的请求集。
    • removePending 方法:
      • 接收一个 AxiosRequestConfig 对象。
      • 首先通过 getPendingUrl(config) 生成请求的唯一标识 url
      • 检查 pendingMap 中是否存在该唯一标识。如果存在,则获取对应的取消函数,调用取消函数来取消当前请求,并从 pendingMap 中删除该请求的标识和取消函数。
    • reset 方法:
      • 将 pendingMap 重新初始化为一个新的 Map 对象,实现对请求管理状态的重置。

用途

在复杂的前端应用中,可能会出现多个并发的网络请求,尤其是在用户频繁操作导致重复请求的情况下。这个工具可以帮助管理这些请求,确保不会因为重复请求而浪费资源或导致数据不一致。例如,在用户快速切换页面或进行频繁的搜索操作时,可以使用这个工具来取消之前未完成的请求,提高应用的性能和用户体验。

以下是对这段代码按代码块再次进行更详细的分析:

一、导入模块和工具函数

import axios, { AxiosRequestConfig, Canceler } from 'axios';
import qs from 'qs';

import { isFunction } from '@/utils/is/index';
  • axios是一个流行的用于浏览器和 Node.js 的 HTTP 客户端,可以方便地发送各种 HTTP 请求。在这里,导入了axios库本身以及特定的类型AxiosRequestConfig(用于配置请求的对象类型)和Canceler(取消请求的函数类型)。
  • qs是一个用于处理查询字符串的库,可以将对象序列化为查询字符串格式,方便在发送请求时处理参数。
  • isFunction是一个自定义的工具函数,用于判断一个值是否为函数,从特定的模块路径中导入。

二、定义请求标识存储容器

// 声明一个 Map 用于存储每个请求的标识 和 取消函数
let pendingMap = new Map<string, Canceler>();
  • 创建了一个名为pendingMapMap数据结构。这个Map将用于存储每个请求的唯一标识(字符串类型)以及对应的取消函数(Canceler类型)。这样可以方便地跟踪和管理正在进行的请求,以便在需要时取消它们。

三、生成请求唯一标识函数

export const getPendingUrl = (config: AxiosRequestConfig) =>
  [config.method, config.url, qs.stringify(config.data), qs.stringify(config.params)].join('&');

  • 定义了一个名为getPendingUrl的函数,该函数接收一个AxiosRequestConfig类型的参数config
  • 函数内部通过获取请求的方法(config.method)、URL(config.url)、请求数据(如果有,使用qs.stringify(config.data)将数据序列化为查询字符串格式)以及查询参数(如果有,使用qs.stringify(config.params)序列化),然后将这些部分用&连接起来,生成一个唯一的请求标识字符串。
  • 这个唯一标识将用于区分不同的请求,以便在pendingMap中进行存储和管理。

四、定义请求取消管理类

export class AxiosCanceler {
  /**
   * 添加请求
   * @param {Object} config
   */
  addPending(config: AxiosRequestConfig) {
    this.removePending(config);
    const url = getPendingUrl(config);
    config.cancelToken =
      config.cancelToken ||
      new axios.CancelToken((cancel) => {
        if (!pendingMap.has(url)) {
          // 如果 pending 中不存在当前请求,则添加进去
          pendingMap.set(url, cancel);
        }
      });
  }

  • 定义了一个名为AxiosCanceler的类,并在其中定义了addPending方法。
  • addPending方法接收一个AxiosRequestConfig类型的参数config,表示要添加的请求的配置。
  • 方法首先调用this.removePending(config),这可能是为了确保在添加新请求之前,先移除可能存在的重复请求。
  • 然后调用getPendingUrl(config)生成请求的唯一标识url
  • 接着检查请求配置中是否已经存在取消令牌(cancelToken)。如果不存在,则创建一个新的取消令牌,并将其与生成的唯一标识关联起来。如果pendingMap中不存在当前请求的标识,则将取消函数添加到pendingMap中,以便后续可以通过这个唯一标识来取消该请求。
  /**
   * @description: 清空所有pending
   */
  removeAllPending() {
    pendingMap.forEach((cancel) => {
      cancel && isFunction(cancel) && cancel();
    });
    pendingMap.clear();
  }

  • 定义了removeAllPending方法。
  • 这个方法遍历pendingMap中的每个取消函数,对于每个取消函数,如果它存在并且是一个函数,则调用该取消函数来取消对应的请求。
  • 最后,清空pendingMap,以便重新开始管理新的请求集。
  /**
   * 移除请求
   * @param {Object} config
   */
  removePending(config: AxiosRequestConfig) {
    const url = getPendingUrl(config);

    if (pendingMap.has(url)) {
      // 如果在 pending 中存在当前请求标识,需要取消当前请求,并且移除
      const cancel = pendingMap.get(url);
      cancel && cancel(url);
      pendingMap.delete(url);
    }
  }

  • 定义了removePending方法,接收一个AxiosRequestConfig类型的参数config
  • 方法首先通过getPendingUrl(config)生成请求的唯一标识url
  • 然后检查pendingMap中是否存在该唯一标识。如果存在,则获取对应的取消函数,调用取消函数来取消当前请求,并从pendingMap中删除该请求的标识和取消函数。
  /**
   * @description: 重置
   */
  reset(): void {
    pendingMap = new Map<string, Canceler>();
  }
};
  • 定义了reset方法。
  • 这个方法简单地将pendingMap重新初始化为一个新的Map对象,实现了对请求管理状态的重置。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值