情景
首次进入,在app.js的onLaunch获取数据(如userInfo),希望在某个页面使用这个数据,但获取数据的过程是异步的,因此获取时可能还没有得到异步返回结果。
问题代码
// app.js
App({
globalData: {
userInfo: null,
},
onLaunch() {
this.getUserInfo()
},
getUserInfo() {
return new Promise(resolve => {
setTimeout(() => {
const userInfo = { name: '小明', age: 18 }
this.globalData.userInfo = userInfo
resolve()
}, 2000)
})
},
})
问题
如果我希望在index.js中获取到这个userInfo,可以直接获取getUserInfo的Promise结果,但会额外产生一次异步请求,带来不必要的网络开销。并且,如果业务涉及到了多个入口页面,这些页面都会出现难以获取到userInfo的问题。
解决方式
在需要使用userInfo的页面,先拿到app实例,再在app实例上添加一个方法,入参是回调函数
// index.js
const app = getApp()
Component({
lifetimes: {
created() {
app.isUserInfoReadyCallback = userInfo => {
console.log(userInfo)
}
},
},
})
app.js异步请求成功后调用外部添加的这个函数,传入请求到的数据即可
// app.js
App({
globalData: {
userInfo: null,
},
onLaunch() {
this.getUserInfo()
},
getUserInfo() {
return new Promise(resolve => {
setTimeout(() => {
const userInfo = { name: '小明', age: 18 }
this.globalData.userInfo = userInfo
if (this.isUserInfoReadyCallback && typeof this.isUserInfoReadyCallback === 'function') {
this.isUserInfoReadyCallback(userInfo)
}
resolve()
}, 2000)
})
},
})
进一步封装
在app.js内添加函数getUserInfoSync,如果userInfo已存在就直接返回,不存在就等待并执行异步回调
# app.js
getUserInfoSync() {
return new Promise(resolve => {
let userInfo = this.globalData.userInfo
if (!userInfo) {
this.isUserInfoReadyCallback = userInfo => {
resolve(userInfo)
}
} else {
resolve(userInfo)
}
})
}
使用
任意需要用到userInfo(数据)的页面,如果userInfo已存入globalData,会直接返回,没存入会等待异步回调
lifetimes: {
async created() {
const userInfo = await app.getUserInfoSync()
console.log(userInfo)
},
}