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

如何避免多次重复发起可选的JavaScript fetch请求(URL 'c')?

问题:复用异步请求结果,避免重复调用URL 'c'

需要访问三个URL:a和b一定会被请求,c则根据a和b的返回结果决定是否请求(0次、1次或2次)。但如果a和b都需要c的结果,不想发起两次fetch('c'),而是复用第一次请求的结果,同时要保证非必要时不请求c。

用户初始实现(存在重复请求问题):

fetch('a')
.then(response => response.json())
.then(data => {
  if (data.value == '1') {
    fetch('c')
    .then(response => response.json())
    .then(data => console.log('through a', data));
  }
})
fetch('b')
.then(response => response.json())
.then(data => {
  if (data.value == '1') {
    fetch('c')
    .then(response => response.json())
    .then(data => console.log('through b', data));
  }
})

用户尝试封装后仍会重复请求:

const c = () => {
  return new Promise(() => {
    fetch('c')
    .then(response => response.json());
  })
}

fetch('a')
.then(response => response.json())
.then(data => {
  if (data.value == '1') {
    c().then(data => console.log('through a', data));
  }
})
fetch('b')
.then(response => response.json())
.then(data => {
  if (data.value == '1') {
    c().then(data => console.log('through b', data));
  }
})

解决方案:缓存Promise实例实现请求复用

核心思路是缓存fetch('c')返回的Promise实例:第一次调用时发起请求并保存Promise,后续调用直接返回这个已存在的Promise,这样无论多少地方调用,实际只会发起一次请求,所有调用都会共享最终结果。

修改后的正确代码:

// 缓存Promise实例,初始为null
let cPromise = null;

const getC = () => {
  // 仅当未发起过请求时,才创建并缓存Promise
  if (!cPromise) {
    cPromise = fetch('c')
      .then(response => response.json())
      // 可选:请求失败时重置缓存,允许后续重试
      .catch(error => {
        cPromise = null;
        throw error;
      });
  }
  // 返回缓存的Promise,无论是否已完成
  return cPromise;
}

// 处理URL a的请求
fetch('a')
  .then(response => response.json())
  .then(data => {
    if (data.value === '1') {
      getC().then(result => console.log('through a', result));
    }
  });

// 处理URL b的请求
fetch('b')
  .then(response => response.json())
  .then(data => {
    if (data.value === '1') {
      getC().then(result => console.log('through b', result));
    }
  });

关键细节:

  • 缓存Promise而非结果:即使第一个请求还在pending状态,后续调用getC()也会等待同一个Promise的完成,不会重复发起请求。
  • 异常处理优化:如果fetch('c')失败,重置cPromise为null,避免后续调用一直拿到失败的Promise,允许重新发起请求。
  • 严格符合需求:只有当a或b的结果需要时才会触发c的请求;若两者都需要,仅发起一次请求并复用结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 21:15:29