使用缓存API和Promise调用getUserProfile 报错的一些踩坑总结
发布于 3 年前 作者 ping60 4599 次浏览 来自 分享

我按照微信小程序文档的说明, 修改了旧的用户资料代码.

所以参考了https://developers.weixin.qq.com/community/develop/article/doc/00000cc422c12844b4fb644d056813 这篇文章,结合缓存保存用户资料,

(这篇文章的代码逻辑没有毛病, 是我的实现有问题)

但是使用了getStorage接口和Promise的形式时,出现了下面图片的错误(当然了, 已排除不用bindtap的了)

有坑的代码:

//func.....
//cache_key...
return new Promise((resolve, reject) => {
     //----------有问题的代码----------
    wx.getStorage({
      key: cache_key,
      success(res) {
        //缓存的数据已经过期,则重新弹出授权窗口,获取用户信息
        if (res.data.expireTime < new Date() * 1) {
          myGetUserProfile(desc, resolve, reject)
        } else {
          resolve({
            userInfo: res.data,
            read_cachetrue
          })
        }
      },
      fail(err) {
        console.error(err)
        myGetUserProfile(desc, resolve, reject) /**问题在这里 */
      }
    });
//    ----------有问题的代码----------

//这是自己写的代码,结合Promise
         function myGetUserProfile(desc, resolve, reject{
              console.log('call myGetUserProfile func', desc)
              wx.getUserProfile({
                desc: desc || ""// 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写
            success(res) => {
              // console.log(res.errMsg, res.userInfo)
              res.userInfo.expireTime = new Date() * 1 + 86400000;
              //保存到缓存中
              wx.setStorage({
                key: cache_key,
                data: res.userInfo || {}
              })
              resolve({
                userInfo: res.userInfo,
                read_cachefalse
              })
            },
            fail(err) {
              console.log("getUserProfile fail: ", err)
              reject(err)
            }
          })
        }
    }

我原来的想法是: 当第一次运行时, 缓存内没有value, 则会调用wx.getStorage.fail ,进而调用myGetUserProfile弹窗授权读取用户资料. 第二次之后判断过期时间,返回缓存的数据或者重新调用myGetUserProfile弹窗授权.

想法是可行的, 理论上也是可行的,代码看起来也是没毛病, 在模拟器操得很畅爽.

按道理上也能讲得通, wx.getStorage 是异步的, 触发fail时,表明第一次时, 不存在值, ........

但是, 放到真机上就不一样了, :(

所以出现了这样的错误:

----------------------------------------------------------------cao ni ma 的分隔线------------------------------------------------------------------------------


经过不断的折腾, 嘴里口吐芬芳,最后才怀疑是上面的代码有问题,

后来改用到了wx.getStorage的同步版本wx.getStorageSync

修改后的代码如下:

try {
      //使用同步版本
      var cache_value = wx.getStorageSync(cache_key);
      console.log('read cache data = ', cache_value)
      if (cache_value) {
        /**有缓存值 */
        // Do something with return value
        //缓存的数据已经过期,则重新弹出授权窗口,获取用户信息
        if (cache_value.expireTime < new Date() * 1) {
          myGetUserProfile(desc, resolve, reject)
        } else {
          resolve({
            userInfo: cache_value,
            read_cache: true
          })
        }
      } else {
        /**没有缓存值 */
        myGetUserProfile(desc, resolve, reject)
      }
    } catch (err) {
      // Do something when catch error
      console.log("getStorageSync fail: ", err)
      reject(err) /* 这里直接抛出去*/
    }

总结的经验, fail的函数与Promise结合, 会出现上面的问题,

上文纯粹是我对这问题的描述和总结, 有错误的请指出, 有更新的方案请指教


回到顶部