
本文介绍如何通过 Promise 缓存机制,确保一个可选的 fetch 请求(如 URL 'c')在多处调用时仅真实发起一次,避免重复网络请求,提升性能与资源利用率。
本文介绍如何通过 promise 缓存机制,确保一个可选的 `fetch` 请求(如 url 'c')在多处调用时仅真实发起一次,避免重复网络请求,提升性能与资源利用率。
在实际前端开发中,常遇到这样的场景:多个逻辑分支可能条件性地触发同一个后端接口(例如配置获取、权限校验或共享数据源),但该接口耗时较长或存在调用限制。若不加控制,多次调用将导致冗余请求、响应不一致甚至服务端压力激增。理想方案是——首次调用时发起真实请求,后续调用直接复用已解析的 Promise 结果(即“懒加载 + 单例 Promise”)。
核心思路是:将 fetch('c') 封装为一个函数,该函数返回同一个 Promise 实例(而非每次都新建),且仅在第一次被调用时初始化请求。JavaScript 提供了简洁高效的实现方式——利用 空值合并赋值运算符 ??= 配合闭包变量缓存:
let cPromise;
const fetchC = () => {
return (cPromise ??= fetch('c')
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
})
);
};
// 使用示例
fetch('a')
.then(res => res.json())
.then(data => {
if (data.value === '1') {
fetchC().then(result => console.log('through a', result));
}
});
fetch('b')
.then(res => res.json())
.then(data => {
if (data.value === '1') {
fetchC().then(result => console.log('through b', result));
}
});✅ 关键优势说明:
- cPromise ??= ... 保证 fetch('c') 仅执行一次:??= 仅在左侧操作数为 null 或 undefined 时才赋值,后续调用直接返回已缓存的 Promise;
- 返回的是原生 Promise,天然支持 .then()、await 及 Promise.all() 等所有 Promise 操作;
- 错误处理内聚:建议在 .then() 中检查 response.ok,避免静默失败;
- 无第三方依赖,兼容现代浏览器(Chrome 85+、Firefox 79+、Safari 14.1+)及 Node.js 16+。
⚠️ 注意事项:
立即学习“Java免费学习笔记(深入)”;
- 若需支持多次独立执行(例如强制刷新),应额外提供 invalidateC() 方法重置 cPromise = null;
- 此模式不适用于需携带动态参数的请求(如 fetch('c?ts=' + Date.now())),此时需扩展为带参缓存(如 Map 键值对);
- 在 SSR(服务端渲染)环境中,注意全局变量 cPromise 的生命周期——每个请求应有独立作用域,避免跨用户数据污染。
总结而言,通过 ??= 运算符实现的单例 Promise 模式,是以极简代码达成高性能请求去重的经典实践。它兼顾可读性、健壮性与标准兼容性,是现代 JavaScript 异步编程中值得掌握的基础范式。










