为什么 Pinia + localForage 持久化后,页面初始化拿不到数据?

最近在给 Pinia 实现持久化时遇到了一个问题:

ini 复制代码
const userStore = useUserStore();

console.log(userStore.token);

明明数据已经保存到 localForage 中,但页面首次加载时拿到的却是默认值。

而在异步代码中:

scss 复制代码
await nextTick();

console.log(userStore.token);

或者:

javascript 复制代码
setTimeout(() => {
  console.log(userStore.token);
}, 100);

却能够正常获取到持久化后的数据。

问题原因

问题的根源在于:

Pinia 的初始化是同步的,而 localForage 的数据读取是异步的。

当执行:

ini 复制代码
const userStore = useUserStore();

时,Pinia 会立即创建 Store:

scss 复制代码
创建 Store
↓
执行 state()
↓
返回 Store

此时 Store 中的数据还是默认值:

css 复制代码
{
  token: ""
}

而 localForage 底层使用的是 IndexedDB,读取数据需要异步执行:

ini 复制代码
const cache = await localforage.getItem("user");

因此会出现下面的执行顺序:

perl 复制代码
创建 Store
↓
返回默认 state
↓
页面开始渲染
↓
localForage 开始读取缓存
↓
缓存读取完成
↓
store.$patch(cache)

也就是说:

复制代码
Store 已创建
≠
持久化数据已恢复

所以页面初始化时拿到的是默认值,而不是缓存中的值。

为什么 localStorage 没有这个问题?

因为 localStorage 是同步 API:

ini 复制代码
const cache = localStorage.getItem("user");

执行流程:

复制代码
读取缓存
↓
恢复数据
↓
返回 Store

Store 返回时数据已经恢复完成,因此组件中能够直接获取到最新状态。

一个常见误区

很多人会这样写:

ini 复制代码
pinia.use(async ({ store }) => {
  const cache = await localforage.getItem(store.$id);

  if (cache) {
    store.$patch(cache);
  }
});

以为加了 async/await 后 Pinia 会等待数据恢复。

实际上并不会。

Pinia 插件本身是同步执行的,Store 不会等待异步任务结束才创建完成。

所以即使使用:

dart 复制代码
pinia.use(async () => {})

也无法阻止 Store 先返回。

总结

这个问题本质上不是 Pinia 的问题,也不是 localForage 的问题,而是同步初始化与异步恢复之间的时间差导致的。

复制代码
Pinia Store 创建:同步

localForage 数据读取:异步

因此当页面首次渲染时:

复制代码
Store 已存在
数据未恢复

而等异步读取完成后:

复制代码
Store 已存在
数据已恢复

这就是为什么在页面初始化阶段拿不到值,而在异步代码中却能够正常获取到值的原因。

本文部分内容借助 AI 辅助生成,并由作者整理审核。

相关推荐
小马过河R16 分钟前
EdgeOne深度解析:从原理、适用场景到COS接入的技术逻辑
java·开发语言·前端·spring·cos
ZoeLandia34 分钟前
TypeScript 04:类型断言与类型守卫
开发语言·前端·typescript
guzicheng199037 分钟前
webpack 安装笔记:全局 vs 本地,以及一个 PATH 环境变量的坑
前端·webpack
西索斯coding43 分钟前
Claude Code 工具调用返回空怎么办?claude-opus-5.5 的 input_schema 校验踩坑记录与修复方案
服务器·前端·javascript·ai
疯狂敲代码的老刘44 分钟前
MarvellousSuspender浏览器扩展:1.4K星开源标签页冻结神器,Chrome吃内存终结者的干净复活版
前端·chrome
码上上班1 小时前
shell 脚本知识点总结
前端·chrome
程序员Sunday1 小时前
Flex 和 Grid 有什么区别?一维布局、二维布局怎么选?
前端·css·面试
Jlzn88881 小时前
华南PACK线自动化率怎么统计才靠谱
前端·javascript·自动化
拖孩1 小时前
AI 时代,个人开发者到底能不能靠一个小程序赚到钱
前端·后端·微信小程序
Hilaku1 小时前
ERP选型时不问MCP,等于默认三年后再付一次集成费!
前端·javascript·程序员