如何避免多次重复发起可选的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
相关产品推荐
相关产品推荐

