微信小程序wx.setStorage数据缓存实现缓存过期时间

@一棵菜菜  September 26, 2018

我接到的需求

在购物车列表页面,点击关闭降价提醒的时候会把当前显示的文案(mainData.cart.cart_popups.txt)和当前时间缓存下来,下次刷新的时候,拿新的降价文案和缓存的对比,如果不一样,就显示新的。如果一样,就继续对比当前时间和上一次缓存的时间有没有超过delay那个时间,如果没超过就不显示,反之显示。

这个时间是换算成时间戳,时间差是25秒(mainData.cart.cart_popups.delay字段),这个是配置的。

cart_popups:{
delay:25,
item_keys:["7021052500026_ht141023p2224148t1"],
txt:"购物车有1件商品降价了",
type:"bottom"
}
/**
   * 关闭顶部的降价提示条
   */
  closeReducePriceTips() {
    this.setData({
      isShowReducePriceTips: false
    });
    // 缓存当前显示的文案和过期时间(ms)
    const timeStamp = +new Date();
    const reducePriceData = {
      text: this.data.mainData.cart.cart_popups.txt,
      expires:
        timeStamp +
        parseInt(this.data.mainData.cart.cart_popups.delay, 10) * 1000
    };

    wx.setStorage({
      key: 'reducePriceTips',
      data: reducePriceData
    });
  },

微信的数据缓存介绍

为了项目性能等方面的考虑,有时候有必要为用户经常访问的页面使用缓存机制;在技术上,服务端和前端都有相应的缓存机制。比如传统的session及cookie等等,在微信小程序中,并没有cookie机制,但有本地缓存。小程序官方文档对本地缓存的介绍如下(传送门):

每个微信小程序都可以有自己的本地缓存,可以通过 wx.setStorage(wx.setStorageSync)、wx.getStorage(wx.getStorageSync)、wx.clearStorage(wx.clearStorageSync)可以对本地缓存进行设置、获取和清理。同一个微信用户,同一个小程序 storage 上限为 10MB。localStorage 以用户维度隔离,同一台设备上,A 用户无法读取到 B 用户的数据。

注意: 如果用户储存空间不足,我们会清空最近最久未使用的小程序的本地缓存。我们不建议将关键信息全部存在 localStorage,以防储存空间不足或用户换设备的情况。

上面一句翻译成简洁的话就是:本地缓存localStorage存在于客户端中,不同用户所对应的缓存数据是相互独立并且因设备而隔离的,而且是持久存储(除非用户清空该小程序的数据)

实际开发

在项目开发过程中,我们利用缓存机制的时候,一般的都需要设置一个过期时间,而不管是session还是cookie我们除了可以设置、获取和清理缓存外,我们可以在设置缓存的同时设置一个“过期时间”。而从以上小程序关于数据缓存API的介绍中,我们并没有看到关于数据缓存过期时间设置的API。

存在的问题

那么这样似乎对于很多需要使用到缓存机制的场景留下遗憾,以我们的小程序为例,首页的几乎所有的数据全部是通过服务端API提供的数据,如果每次刷新小程序页面都需要重新通过wx.request这个接口拉取数据,那么花在网络请求的时间至少是100ms以上,这不仅不利于用户体验也浪费了计算资源。而如果,直接按照文档中的表面化的应用数据缓存API,那么数据会持久化存储,那么首页中包括案例以及其他动态更新的数据怎么更新?

解决办法

那么是不是就必须留下这样的遗憾呢?如果果然会留下这样的遗憾,那么我相信腾讯肯定会解决这样的问题的。其实我们可以参考诸如cookie这样的缓存机制,我们自己“造”一个过期时间。在设置某缓存数据A的时候,我们可以同时设置一个过期时间值的数据缓存B;在下一次打开该页面的时候,不仅需要判断数据A是否存在,也需要比较B与当前时间,如果符合要求则使用本地缓存的数据A,否则则重新拉取数据并刷新A和B。以上逻辑翻译成代码则为如下,首先是拉取服务端数据成功后同时设置两个数据缓存,

setStorage.png

以上的index_data是我们需要设置的缓存数据,而index_data_expiration则是与之对应的时间数据,其中3000000则是3000s,当用户进入该页面时,进行缓存数据判断:
下图错误之处,expiration、index_data应是object

getStorage.png

在项目实践过程中,我们可以根据以上逻辑把这种方法封装起来;此外,缓存的过期时间,我们也可以读取服务端设置的超时时间,这样小程序发布后我们可以在服务端灵活变更调节具体的数值了。

文章来源

添加新评论