if块内await未等待导致Sequelize缓存初始化失败
问题分析与解决
核心问题出在 FFMStates.get() 方法的异步逻辑处理上:如果 get() 未声明为异步函数,内部的 await 会被当作普通表达式跳过,不会等待 load() 执行完成就直接返回未初始化的 DATA。
常见错误代码示例
// 错误写法:get方法未声明为async,await不生效 const FFMStates = { DATA: null, TTL: 3600000, lastLoaded: 0, load() { return sequelize.models.FFMState.findAll({ raw: true }); }, get() { const now = Date.now(); if (!this.DATA || now - this.lastLoaded > this.TTL) { // 此处await无效,get会直接跳过等待执行return await this.load().then(data => { this.DATA = data; this.lastLoaded = now; }); } return this.DATA; // 首次调用直接返回null } };
正确修复方案
- 把
get()声明为异步函数,确保内部await能阻塞到load()完成 - 统一用
await处理异步逻辑,避免混合await和.then()导致的逻辑混乱 - 新增并发控制标记,防止高并发下重复触发数据库查询
const FFMStates = { DATA: null, TTL: 3600000, lastLoaded: 0, isLoading: false, // 防止并发重复加载 async load() { try { const data = await sequelize.models.FFMState.findAll({ raw: true }); this.DATA = data; this.lastLoaded = Date.now(); return data; } catch (err) { console.error('FFMStates加载失败:', err); throw err; // 抛出错误让调用方处理 } }, async get() { const now = Date.now(); // 检查缓存是否过期或未初始化 if (!this.DATA || now - this.lastLoaded > this.TTL) { if (this.isLoading) { // 已有加载请求,等待其完成 await new Promise(resolve => { const checkTimer = setInterval(() => { if (!this.isLoading) { clearInterval(checkTimer); resolve(); } }, 50); }); } else { this.isLoading = true; await this.load(); this.isLoading = false; } } return this.DATA; } };
正确调用方式
调用时必须使用 await,因为 get() 已改为异步函数:
const states = await FFMStates.get(); // 后续基于states执行业务逻辑
额外优化建议
- 可以给
DATA设置初始默认值,避免首次加载前返回null - 可根据业务需求调整
TTL时长,或给缓存增加主动刷新方法
内容的提问来源于stack exchange,提问作者SunnyPro
相关产品推荐
相关产品推荐

