用 promise 缓存初始化请求是最直接有效的方式:通过模块顶层共享同一 promise 实例,确保初始化逻辑只执行一次,后续调用复用已 settled 的 promise,避免重复请求,并支持重试、超时及统一错误处理。

用 Promise 缓存初始化请求是最直接有效的方式:同一个初始化逻辑只执行一次,后续调用直接复用已 resolve 的 Promise 实例。
共享一个 Promise 实例
把初始化请求封装成一个变量,在模块顶层定义,所有地方都引用它,而不是每次调用都新建 Promise。
- 初始化逻辑(如加载配置、获取用户信息)只在第一次调用时触发
- 后续调用直接拿到已 settled 的 Promise,不会重复发请求
- 注意不要在函数内部 new Promise(),否则每次调用都会新建
示例:
let initPromise;function initApp() {
if (!initPromise) {
initPromise = fetch('/api/config').then(res => res.json());
}
return initPromise;
}
用闭包或模块级变量隔离作用域
避免多个模块各自维护自己的 initPromise,导致缓存不共享。推荐统一导出一个初始化函数,或使用单例式模块封装。
- 把 initPromise 放在独立的 utils/init.js 中,各模块 import 同一份
- 如果用 ES 模块,顶层声明的变量天然单例,适合做 Promise 缓存
- 不建议每个模块自己写一套 init 逻辑,容易冲突或重复
支持重试与状态清理(可选进阶)
如果初始化失败需要重试,或某些场景下要强制刷新缓存,可以扩展控制逻辑。
- 加一个 reset() 方法清空 initPromise,下次调用重新发起请求
- 失败时不要直接 reject,而是保留 Promise 引用,让调用方决定是否重试
- 可以用 Promise.race() 配合超时控制,避免卡死
例如:
let initPromise = null;export function initApp(force = false) {
if (force) initPromise = null;
if (!initPromise) {
initPromise = fetch('/api/config')
.then(res => { if (!res.ok) throw new Error(); return res.json(); })
.catch(err => { initPromise = null; throw err; });
}
return initPromise;
}
配合 async/await 使用更自然
调用端无需关心 Promise 是否已 resolve,统一 await 即可,语义清晰且自动处理缓存和等待逻辑。
- 多个组件同时 await initApp(),实际只发一次请求,其余等待同一 Promise 完成
- 即使并发调用,也天然串行化——因为 Promise 是共享的,不是多次执行
- 错误会被所有 await 处捕获,便于统一处理
示例:
async function renderPage() {try {
const config = await initApp();
renderWithConfig(config);
} catch (err) {
showError(err);
}
}
不复杂但容易忽略:关键是让所有模块共用同一个 Promise 引用,而不是各自创建。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











