You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现getOrFetchCategoriesList避免重复发送未完成的后端请求

问题分析

你现有的代码存在两个核心问题:

  1. 分支逻辑有缺陷:if (categories.length)和if (!categories.length)已经覆盖了所有分支,categoriesLoading的判断分支永远不会被执行
  2. 没有存储 pending 状态的请求实例,就算进入加载中分支也没有可等待的对象

最优实现方案

我们可以直接用一个 Promise 变量同时承担「状态标识」和「结果缓存」的作用,不需要单独维护加载状态和结果变量,实现更简洁也更可靠:

// 全局存储分类请求的Promise,初始为null
let categoriesPromise: Promise<Category[]> | null = null;

const getOrFetchCategoriesList = async (): Promise<Category[]> => {
  // 已经存在请求Promise(不管是 pending 还是已 resolve),直接返回即可
  if (categoriesPromise) {
    return categoriesPromise;
  }

  // 无请求时发起新请求,将Promise存入全局变量
  categoriesPromise = (async () => {
    const response: ElasticsearchAnswer = await fetchCategoryList();
    return response.hits.hits.map(hit => hit._source);
  })();

  return categoriesPromise;
};

// 可选:如果后续有清空缓存重新请求的需求,可以增加重置方法
const resetCategoriesCache = () => {
  categoriesPromise = null;
};

逻辑说明

这个实现完全覆盖你提出的三个要求:

  • 首次调用时categoriesPromise为null,会发起新请求
  • 请求成功后categoriesPromise处于已 resolve 状态,后续所有调用都会直接返回缓存的结果,不会重复发起请求
  • 请求过程中如果有新的调用,会直接返回同一个 pending 状态的Promise,所有调用方都会等待同一份请求结果,不会发起重复请求

内容的提问来源于stack exchange,提问作者Nimble Stalker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.13 20:24:01