HTML5 的 localStorage/sessionStorage 需封装为 Promise 接口以支持 async/await,同时需处理序列化、命名空间、错误降级等工程问题。

在 HTML5 中,localStorage 和 sessionStorage 原生只提供同步的 setItem、getItem、removeItem 等方法,无法直接用于 async/await 或链式 Promise 流程。封装一个支持 Promise 接口的异步存储装饰器,能统一异步调用风格、便于错误处理和组合使用。
基础 Promise 包装器
最简实现是将原生方法包装为返回 Promise 的函数,不改变行为,仅适配异步上下文:
-
getItem(key)→ 返回Promise<string null></string> -
setItem(key, value)→ 返回Promise<void></void>,失败时 reject(如超出配额) -
removeItem(key)→ 返回Promise<void></void> -
clear()→ 返回Promise<void></void>
注意:所有操作本身仍是同步执行,Promise 仅用于统一接口和异常转译,不是真正“异步 IO”——这是浏览器规范限制,不可绕过。
支持序列化与类型安全的装饰器
原生只接受字符串,但实际常需存对象、布尔、数字等。装饰器可自动序列化/反序列化,并附带泛型提示:
- 写入时自动
JSON.stringify(value),失败则 reject 错误 - 读取时自动
JSON.parse(str),对无效 JSON 返回null或抛错(可配置) - TypeScript 下可定义
getJson<t>(key): Promise<t null></t></t>提升类型推导
例如:storage.setJson('user', { id: 1, name: 'Alice' }) 内部存为字符串,读取时自动还原为对象。
带前缀与命名空间的模块化封装
避免 key 冲突,装饰器可内置命名空间前缀(如 'app:v1:'),并支持多实例隔离:
- 构造时传入
namespace = 'myapp',所有 key 自动拼接为'myapp:theme' - 支持
createStorage({ storage: sessionStorage })切换底层引擎 - 可扩展中间件,如加密(存前 AES 加密)、压缩(大文本 LZUTF8 压缩)
这样既保持 localStorage 原语能力,又获得类似现代库(如 zustand-persist)的工程友好性。
错误处理与降级策略
浏览器环境不可控(私密模式禁用、配额超限、Safari 无痕模式抛错),装饰器应主动兜底:
- 首次调用前探测可用性:
try { localStorage.setItem('__test__', '') } catch - 写失败时 fallback 到内存 Map(
inMemoryStorage),保持 API 不中断 - 读取时对
SecurityError、QuotaExceededError分类处理并 emit warning
这对 PWA、跨设备同步场景尤其关键——不能因存储异常导致整个页面逻辑崩溃。
不复杂但容易忽略:Promise 化只是第一步,健壮的装饰器必须覆盖边界情况,而不是假装 localStorage 是个可靠数据库。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










