Skip to content

如何封装一个请求,让其多次调用的时候,实际只发起一个请求的时候,返回同一份结果?

Posted on:2024年9月3日 at 01:33

封装一个请求使其在多次调用时只发起一次请求,并返回相同结果,通常是通过请求去重(debouncing)来实现的。这种功能对于避免重复的网络请求、提高性能和减少不必要的负载非常有用。

同时,我们需要确保在请求完成之前,对相同请求的重复调用都会共享相同的请求 Promise。避免出现连续发出相同的请求,在第一个请求尚未完成时,那么可能会发出多个请求的情况。

可以通过以下步骤来实现这个功能:

1. 使用一个缓存机制

我们可以使用 JavaScript 对象或 Map 来缓存已经发起的请求,并在 subsequent 请求中返回缓存的结果。缓存的关键是确保相同的请求参数对应同一个缓存条目。

2. 创建请求缓存封装

以下是一个基于 axios 的请求去重的封装示例:

import axios from "axios";

// 请求缓存
const requestCache = new Map();

async function fetchData(url, params) {
  // 生成缓存 key
  const cacheKey = `${url}?${new URLSearchParams(params).toString()}`;

  // 检查缓存中是否已有数据
  if (requestCache.has(cacheKey)) {
    return requestCache.get(cacheKey);
  }

  // 创建请求 Promise
  const requestPromise = axios
    .get(url, { params })
    .then((response) => {
      // 请求成功,存储结果
      requestCache.delete(cacheKey); // 请求完成后,移除缓存
      return response.data;
    })
    .catch((error) => {
      // 请求失败,清除缓存
      requestCache.delete(cacheKey);
      throw error;
    });

  // 存储请求 Promise
  requestCache.set(cacheKey, requestPromise);

  // 返回 Promise
  return requestPromise;
}

export default fetchData;

注意事项:

3. 使用请求缓存

使用封装好的 fetchData 函数来发起请求。多次调用相同的请求 URL 和参数只会发起一次网络请求,并返回相同的结果。

import fetchData from "./fetchData";

// 使用示例
fetchData("https://api.example.com/data", { id: 1 })
  .then((data) => console.log(data))
  .catch((error) => console.error(error));

// 再次调用相同的请求
fetchData("https://api.example.com/data", { id: 1 })
  .then((data) => console.log(data)) // 共享相同的请求结果
  .catch((error) => console.error(error));
原文转自:https://fe.ecool.fun/topic/e902d336-e2dd-4de7-a471-16806c695aa9