onLaunch 函数中的异步方法处理
问题
功能需求,在进入 App 页时调用接口获取一些数据,然后要在活动页中使用。
因为小程序本体只是用来推广活动的,因此不产生跳转等问题,会直接打开活动页。
但是当活动页加载完成,onLaunch 函数内,接口调用的数据却获取不到。
经查询,发现这应该是 uni-app 框架本身的问题,在 onLaunch 钩子内如果调用异步,数据加载顺序就会发生改变。(避坑 🙃)
也就是说在 onLaunch 钩子还在执行异步数据获取的时候,页面的 onLoad 钩子就已经开始执行了。所以获取不到需要的数据体。
解决方法
可以利用 Promise 来解决这个异步数据异常问题。
- 在
main.js中增加以下代码:
js
Vue.prototype.$onLaunched = new Promise(resolve => {
Vue.prototype.$isResolve = resolve
})注册一个 Promise 事件,阻塞页面加载,一会调用。
- 在
App.vue的onLaunch的异步请求中增加Promise的数据返回。
js
onLaunch: async function() {
let {
page_status
} = await this.$u.api.pagesSwitch()
console.log(123)
this.$isResolve() // 这是重点!!!
},执行完异步请求之后,执行 resolve 可以让 Promise 正常结束
- 在页面
onLoad钩子中调用Promise暂停业务代码继续执行,直到App中的异步请求完成,数据体返回。
js
async onLoad(option) {
await this.$onLaunched // 这是重点!!!
console.log(456)
/**
* 业务代码
*/
}如果小程序中有多个页面都需要用到数据,这个方法就有些繁琐。
可以使用 Vue.mixin 进行全局混入执行操作,每个页面在没有获取到数据之前都不会自主加载成功。
- 新建一个
my_mixin.js文件,用于写入混入方法。
js
module.exports = {
async onLoad() {
await this.$onLaunched // 这是重点!!!
console.log(456)
if (this.getDataList) {
this.getDataList() // 这里执行每个页面特定方法
}
}
}- 在
main.js中注册全局混入文件。
js
import myMixin from './common/my_mixin.js'
Vue.mixin(myMixin)事件注册完成,正常 console 显示流程应该是 123 456 如果显示顺序不对,证明方法并没有生效。
方法参考自:瞭月,感谢解决我遇到的问题。愿人间没有 BUG 🤡。