最近在一个小程序里,使用了自定义的tabbar(非自定义组件方式)。其中有个需求是在tabbar上显示badge,并且当远程数据有更新时,需要tabbar上能自动更新badge。
因为服务器资源有限,所有没有使用websocket实现服务端对小程序端的信息推送方式,而是在小程序端使用setInterval设置定时任务从服务端拉取信息。定时拉取信息的方式,在注意控制频率和及时有效销毁定时任务的情况下,对服务器的压力还是挺小的。
又因为不同的Page里面,自定义tabbar是独立的实例,所以考虑再App.js里面实现这套方案。
const MpHelper = require("./utils/MpHelper")//自己的小程序方法工具类
// app.js
App({
onLaunch() {},
onHide(){
//这里要注意销毁定时任务
clearInterval(this.globalData.globalBadgeTimer)
},
onShow(){
//防止有未成功删除旧的定时任务的情况
clearInterval(this.globalData.globalBadgeTimer)
//设置每5分钟获取一次远程badge信息,并更新tabbar
this.globalData.globalBadgeTimer = setInterval(() => {
//调用自己的获取远程badge的方法,我在这个方法里面设置了一个回调函数,也可以用promise的方式实现
//MpHelper.fetchBadgeInfoFromRemote还需要做的一件事是更新globalData中的badgeInfo
MpHelper.fetchBadgeInfoFromRemote(function(bflag, remoteBadgeInfo){
if (bflag) {//远程读取成功
//接下来准备更新tabbar上的badge信息
let currentPages = getCurrentPages()//获取堆栈中的所有页面
if (!MpHelper.isJsonEmpty(currentPages)) {//堆栈可能为空,需要判断一下
let firstTabPage = currentPages[0]//获取堆栈中的第一个页面:这里需要讨论下,我只是主观觉得堆栈中第一个页面必定是tab页
if (!MpHelper.isJsonEmpty(firstTabPage)) {//如果堆栈非空,那么准备获取第一个页面的tabbar实例
if (typeof firstTabPage.getTabBar === 'function' && firstTabPage.getTabBar()) {//判断是否获取到了tabbar实例
firstTabPage.getTabBar().setData({
tab1Badge: remoteBadgeInfo.info1,
tab2Badge: remoteBadgeInfo.info2,
//。。。。。其他的tabbar信息也可以这里设置
})
}
}
}
}
});
}, 300000);//设置5分钟更新一次
},
globalData: {
globalBadgeTimer: 0,//全局的Badge更新
badgeInfo: null,//全局的badgeInfo,所有的Tab-Page在onShow时读取这里的badge信息,而不需要考虑从服务端更新
}
})
有几个问题
- 获取tabbar实例时,通过getCurrentPages()方法,并且认为第一个page就是tab页,是否正确
- 定时任务的方式有“失控”的隐患,有可能对服务端造成较大的压力