Cordova SecureStorage异步执行顺序与JSON解析错误问题咨询
问题1:存储操作晚于updateInputsInConfig执行的成因与解决方案
成因
- 你定义的
_init是异步函数,但调用时没有加await或通过then监听执行结果,直接在_init外层同步调用了updateInputsInConfig,此时_init内的SecureStorage实例初始化、首次set操作还处于未完成的异步状态。 - cordova-plugin-secure-storage的原生API是回调风格,本身不返回Promise,你直接对回调方法使用
await是无效的,无法阻塞后续代码执行,导致执行顺序混乱。
解决方案
先将SecureStorage的回调方法封装为返回Promise的版本,再按异步顺序控制执行逻辑:
// 封装set方法 const ssSet = (key, value) => new Promise((resolve, reject) => { ss.set(resolve, reject, key, value) }) // 封装get方法 const ssGet = (key) => new Promise((resolve, reject) => { ss.get(resolve, reject, key) }) // 封装初始化方法 const initSS = () => new Promise((resolve, reject) => { const ssInstance = new cordova.plugins.SecureStorage( () => resolve(ssInstance), (err) => reject(err), "Stocks2018" ) })
之后修改_init逻辑,确保初始化和首次存储完成后再执行后续逻辑。
问题2:SecureStorage存储的数据是否会在应用关闭后保留
会持久保留。SecureStorage的数据存储在系统原生的密钥链(iOS)/密钥库(Android)中,属于持久化存储,只要不主动调用remove/clear方法删除数据、不卸载应用,即使关闭应用、重启设备,数据都不会丢失。
问题3:JSON解析报错的原因与修复方案
原因
报错里的Unexpected token u本质是你传入JSON.parse的参数是undefined,undefined转成字符串后为"undefined",首字符就是u,不符合JSON格式规范。触发的场景有两种:
- 你对回调风格的
ss.get误用了await,没有正确拿到回调返回的value,导致config变量还是初始的undefined。 - 存储的
configkey不存在,get回调返回的value为undefined。
修复方案
修改updateInputsInConfig逻辑,增加异常捕获和空值判断:
async function updateInputsInConfig(){ if(!ss) return // 避免ss未初始化就调用 try { const configStr = await ssGet("config") // 空值、空对象直接跳过 if(!configStr || configStr === "{}") return const parsed_config = JSON.parse(configStr) // 后续赋值逻辑保持不变 } catch(err) { console.log("配置读取或解析失败:", err) } }
问题4:实现updateInputsInConfig在所有读写完成后执行的方案
- 初始化阶段:在
_init函数完成SecureStorage实例初始化、首次set操作后,再调用updateInputsInConfig:
// 正确的初始化调用逻辑 async function _init() { ss = await initSS() await ssSet("config", JSON.stringify(config)) // 初始化存储完成后再执行表单赋值 updateInputsInConfig() // 绑定点击事件逻辑保持不变 check_btn.addEventListener("click", async () => { // 构造config、global、produtos对象的逻辑保持不变 // 等待所有存储操作完成 await ssSet("config", JSON.stringify(config)) await ssSet("global", JSON.stringify(global)) await ssSet("produtos", JSON.stringify(produtos)) // 存储完成后再更新表单 updateInputsInConfig() navigator.notification.alert("Configurações aplicadas com sucesso!", () => {}, "Sucesso"); }) } // 启动初始化 _init()
- 点击提交阶段:等三个
set操作全部await完成后,再手动调用updateInputsInConfig即可。
内容的提问来源于stack exchange,提问作者Inês Borges
相关产品推荐
相关产品推荐

