- onLoad时调用getStorage等API不resolve的问题
在 onLoad 中,调用 wx.getStorage 和 wx.cloud.callFunction,两者均不 resolve。用 await 以后的表现就是,脚本的执行在该行暂停。但是在下拉刷新中,却不存在此问题,两个接口均在很短的时间内 resolve 。 const { data: localData } = await wx.getStorage({ key, }); const { result: remoteData } = await wx.cloud.callFunction({ name: "getData", data: { key, }, }); 简单改写一下,却能解决问题: const { data: localData } = await new Promise((resolve, reject) => { setTimeout(() => { wx.getStorage({ key }) .then((res) => { resolve(res); } .catch((err) => { reject(err); }); }); }); const { result: remoteData } = await new Promise((resolve, reject) => { setTimeout(() => { wx.cloud .callFunction({ name: "getData", data: { key, }, }) .then((res) => { resolve(res); }) .catch((err) => { reject(err); }); }); }); 结合「下拉刷新的时候却不存在这个问题」,我猜测可能是在 onLoad 的周期内,以上两个接口还未初始化或者其他原因,导致无法正确调用。而使用 setTimeout 将他们强制推迟到下一个周期,或者下拉刷新时,这两个接口已经完成初始化,便不存在问题。 完整函数定义如下: loadPageData: async (page, key, callback = () => {}) => { wx.showLoading({ title: "", }); try { // load from local console.log(`try load ${key} from local...`); const { keys: storageKeys } = await wx.getStorageInfo(); if (storageKeys.includes(key)) { console.log(`the key ${key} exist in local, try loading...`); const { data: localData } = await wx.getStorage({ key, }); console.log({ key, localData, }); if (localData) { page.setData({ pageData: localData, }); wx.hideLoading(); callback(localData); } } else { console.log(`the key ${key} does not exist in local!`); } } catch (err) { console.error(err); } finally { try { // load from remote console.log(`try load ${key} from remote...`); const { result: remoteData } = await wx.cloud.callFunction({ name: "getData", data: { key, }, }); console.log({ key, remoteData, }); if (remoteData) { page.setData({ pageData: remoteData, }); wx.hideLoading(); wx.setStorage({ key: key, data: remoteData, }); callback(remoteData); } } catch (err) { console.error(err); } } },
2021-08-26 - 页面首次调用API不返回结果也不报错,多次调用才能成功。
问题描述: 随着页面 onLoad 中调用的两个API,wx.cloud.callFunction 和 wx.getStorage 都大概率假死。最早是发现 wx.cloud.callFunction 存在这个现象,后来发现 wx.getStorage 也会。页面没有完全卡死,但是调用的API既不返回结果,也不报错,一直处于等待状态。 本来怀疑是后端或者网络的问题,但是后端是云函数,逻辑上没有问题或者超时,并且后来发现调用本地数据 wx.getStorage 也这样,所以和后端还有网络没啥关系。 这个问题只在首次或前几次调用 onLoad 的时候出现,如果下拉刷新(下拉刷新会调用 this.onLoad() ),则多重试一次或多次就会变得正常。 尝试了加入重试机制,1秒内数据未返回便发起下一次尝试,但是这个方法也失败了。这个问题似乎直接阻塞了函数的执行,连setTimeout那一行都运行不到。 经过进一步测试,手机端基础库2.11.2和之前都是好的,2.12开始出现这个故障。仅iOS上存在此问题,Android和开发工具上不存在此问题。 期待官方跟进与解决。 onLoad() { app.loadPageData(this, "faculty_office") }, async loadPageData(page, key, global = false) { wx.showLoading({ title: '', }) try { // load from local console.log("load from local...") const { keys: storageKeys } = await wx.getStorageInfo() if (storageKeys.includes(key)) { const { data: localData } = await wx.getStorage({ key }) console.log({ key, localData }) if (localData) { page.setData({ pageData: localData }, () => { wx.hideLoading() }) if (global) { this.globalData[key] = localData } } } else { console.log("local data does not exist!") } } catch (err) { console.error(err) } finally { try { // load from remote console.log("load from remote...") const { result: remoteData } = await wx.cloud.callFunction({ name: 'getData', data: { key } }) console.log({ key, remoteData }) if (remoteData) { page.setData({ pageData: remoteData }, () => { wx.hideLoading() }) wx.setStorage({ key: key, data: remoteData }) if (global) { this.globalData[key] = remoteData } } } catch (err) { console.error(err) } } }, 云函数部分 exports.main = async (event, context) => { // input parameters const key = event.key // cloud db const db = cloud.database() const collection = db.collection('data') // function body const { data } = await collection.where({ key }).get() var result = {} try { result.data = JSON.parse(data[0].dataString) result.updated = formatDate(new Date(data[0].updated), "YYYY-mm-dd") } finally { return result } } 出错截图: [图片] [图片]
2020-09-03