在uni-app开发中,本地存储是绕不开的基础功能。但你是否遇到过这样的困惑:数据明明存了,却读出来是undefined?或者页面在存储数据时出现了短暂的卡顿?这些问题,往往源于对异步和同步接口的理解偏差。 简单来说,uni.setStorage 和 uni.getStorage 是异步接口,调用后
uni-app本地存储:setStorage与getStorage区别
作者:技术拾光
时间:2026-06-04
浏览:117
文章目录
在uni-app开发中,本地存储是绕不开的基础功能。但你是否遇到过这样的困惑:数据明明存了,却读出来是undefined?或者页面在存储数据时出现了短暂的卡顿?这些问题,往往源于对异步和同步接口的理解偏差。

简单来说,uni.setStorage 和 uni.getStorage 是异步接口,调用后不会立刻拿到结果,需要通过回调函数或Promise来处理。而它们的“Sync”版本——uni.setStorageSync 和 uni.getStorageSync——则是同步接口,调用后会立即返回结果或抛出错误,代价是会暂时阻塞Ja vaScript的主线程。
核心差异:关键在于“确认时机”
这两组接口的根本区别,其实不在于“能不能存储”,而在于“什么时候能确认存储已经完成”。
uni.setStorage是异步操作。当你调用它时,写入请求被提交后函数就立刻返回了,此时数据可能还在排队等待写入,并未真正落盘。因此,所有依赖于“存储完成”的后续逻辑(比如页面跳转、UI更新),都必须放在它的success回调函数里执行。uni.setStorageSync是同步操作。调用它会卡住当前Ja vaScript线程的执行,直到数据被物理写入存储后才继续往下走。对于token、开关状态这类小数据,这种阻塞几乎无感;但如果你要缓存一整页的列表数据,就可能引起可察觉的界面卡顿。- 两者都要求传入的
data必须是可被序列化的值。如果传入了函数、undefined、Symbol或存在循环引用的对象,setStorageSync会静默失败(返回undefined),而setStorage则会在fail回调中明确报出JSON.stringify error。 - 容量限制也需注意。小程序平台(如微信、支付宝)对
setStorageSync的单次写入大小有更严格的限制(通常≤1MB),超限会直接抛出错误。而在H5环境下,这个限制则取决于浏览器的localStorage规范,一般是5到10MB。
读取时为何总遇到undefined?
数据读出来是undefined,很多时候并不是存储失败了,而是读取的时机不对或者键名(key)没匹配上。
- 一个典型场景是:用
uni.setStorage存完数据后,立刻调用uni.getStorage去读,并且没有等待success回调。这大概率会读到旧值或空值,因为写入操作可能还没真正结束。 - 键名是大小写敏感的。
'Token'和'token'会被视为两个完全不同的键。另外,如果存储时参数是一个对象(如{key: 'user', data: obj}),但读取时却漏掉了key字段,直接传了字符串,也会导致参数错误而读取失败。 uni.getStorageSync在查不到对应键名时会直接返回undefined,不会抛出错误。这很容易让人误判为“数据没存进去”,而实际上可能是键名拼写错误,或者是在跨平台调试时(比如在微信开发者工具里点击了“清除数据”)缓存被清空了。- 某些安卓设备的WebView对
JSON.parse的容错性较差。如果之前存储的是一个非法的JSON字符串(例如手动拼接的字符串),getStorageSync可能会静默地返回undefined,而getStorage则会在fail回调中提示解析失败。
如何选择:同步还是异步?
选择哪组接口,不能凭感觉,而要看具体的执行时机和数据的重要性。
- 对于那些**应用一启动就需要、且不能为空**的数据,比如登录态token、用户基础信息,建议使用
uni.getStorageSync同步读取,以避免页面白屏等待。不过,在存储token时,如果用uni.setStorageSync,最好加上try/catch包裹,防止因序列化失败导致数据静默丢失。 - 对于页面级的缓存,比如搜索历史、表单草稿,或者一些非关键性的配置项,可以优先使用
uni.setStorage和uni.getStorage这对异步组合,并配合fail回调做好降级处理(例如读取失败时使用默认值)。 - 如果需要连续多次写入(比如批量保存10条日志),千万不要连续调用多个
setStorageSync,否则主线程会被长时间阻塞。更好的做法是用Promise.all来包裹多个setStorage异步调用。 - 在调试阶段,如果想快速验证某个键是否存在,直接在控制台输入
uni.getStorageSync('xxx')是最快的。但在正式上线的代码里,尤其是在onLaunch生命周期中,应避免无条件地同步读取大量键值,这在iOS小程序上可能会触发性能告警。
最后,还有一个极易被忽略的要点:虽然所有storage接口在不同平台的行为基本一致,但**它们的容量上限和错误提示的详细程度差异可能很大**。例如,在微信小程序里,setStorageSync 超过1MB会直接抛出错误;而在H5环境,超出部分可能只是被静默截断。因此,如果你真的需要存储较大的数据结构,一个稳妥的做法是先用 JSON.stringify 估算一下长度,再决定是分片存储,还是直接使用IndexedDB这类更适合大容量数据的方案。
实用工具推荐
电子包浆
使用 ›绿化、压缩、噪点和虚拟水印,自由调节做旧程度。
图片压缩
使用 ›选择画质和输出格式,预览压缩前后的大小。
相关文章