收藏
回答

onLoad时调用getStorage等API不resolve的问题

框架类型 问题类型 API/组件名称 终端类型 微信版本 基础库版本
小程序 Bug wx.getStorage wx.cloud.callFunction 微信iOS客户端 7.0.15-8.0.11 2.12-2.19.2 (2.11.2之前不存在此问题)

在 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
回答关注问题邀请回答
收藏

1 个回答

  • showms
    showms
    2021-08-26
    wx.getStorage是异步模式,并不支持promise,所以用await没用,如果要马上拿到结果,用wx.getStorageSync不就行了
    
    2021-08-26
    有用
    回复
登录 后发表内容