设想一个场景:开启小程序时,要拉取某些全局数据,其他页面显示依赖这些数据。考虑到网络延迟和失败,如果请求失败需要重复三次,如果终不成功,要给用户提示。如何才能给正在访问某个页面的用户以通知?
把信息存在全局变量中,让页面逻辑代码去查看全局变量是否改变,这种方法不可靠而且耗费资源,因为全局变量改变的时间不定。因此,最好的解决办法是全局逻辑代码去通知页面,即 app.js 发消息给具体页面。
app.js
App({
onLaunch: function () {
setTimeout(function () {
getCurrentPages()[0].showMessage();
}, 5000);
}
})
在需要显示消息的页面 js:
Page({
showMessage() {
this.setData({ msg: "msg from app.js" })
}
})
这样,app.js 就可以刷新当前页面。考虑更一般的情况,我们通常会在 onLoad(), 或 onShow() 中进行页面初始化,其实可以考虑将初始化的功能封装在一个函数中,在 app.js 中获取信息后,也调用这个函数。
由于异步执行,考虑到 页面尚未加载的情况,因此在 app.js 中增加判断:
const global_info = []
const nowPages = getCurrentPages()
if (nowPages.length > 0) { //页面已经加载
if (nowPages[0].hasOwnProperty("showMessage")) {
nowPages[0].showMessage()
}
else {
//wx.setStorageSync("global_info", global_info)
}
}
else { // 页面未加载
//wx.setStorageSync("global_info", global_info)
}
有的同学看了官方文档,可能会有疑问,因为官方文档这样写:
不要在 App.onLaunch 的时候调用 getCurrentPages(),此时 page 还没有生成。
但是,前面设计的调用方式是可行的,因为,这里处理的信息是请求自服务器,返回会有延迟。服务器返回结果时,
- 如果在其他页面已经加载的情况下,这是调用 getCurrentPages() 是安全的。
- 如果其他页面未加载,getCurrentPages() 获取不到页面。但这时信息会保存到内存或 app.js 里的变量,其他页面加载时,就可以取得这些信息。
另外,在某个页面,当要触发一个异步消息给其他页面时,最好的方法还是交给 app.js 来管理。
最后介绍一个任务管理小程序:小助手bot,使用了上面介绍的方法: