一网打尽,全面解决uni-app中App.vue和页面的异步问题
2022-12-09 12:30:15
App.vue 和 onLoad 函数的异步困境:症结所在与解决方案
异步的本质
在 uni-app 中,App.vue 的 onLaunch 函数负责初始化应用程序的状态和数据。然而,页面中的 onLoad 函数可能会在 onLaunch 函数执行完毕之前触发,导致页面无法访问 App.vue 中初始化的数据,从而出现渲染或数据加载问题。
症结所在
这种异步问题源于 JavaScript 的异步执行机制。在 onLaunch 函数中,JavaScript 会异步获取数据,而 onLoad 函数则在页面加载时立即执行。由于 JavaScript 的非阻塞特性,onLoad 函数可能在 onLaunch 函数返回数据之前就被执行,导致数据无法及时获取。
解决方案:驾驭异步
**1. 使用 await 和 async **
在 onLoad 函数中,可以使用 await 等待 onLaunch 函数执行完毕,然后再初始化页面数据。同时,在 onLaunch 函数中使用 async 关键字标记其为异步函数。
// App.vue
export default {
async onLaunch() {
const data = await fetchData();
this.$store.commit('setData', data);
}
}
// Page.vue
export default {
onLoad() {
this.data = this.$store.state.data;
}
}
2. 使用 $onLaunched 事件:
onLoad 函数中可以使用 onLaunched 事件监听 onLaunch 函数执行完毕。当 onLaunch 函数完成时,onLaunched 事件会被触发,页面可以开始初始化数据。
// Page.vue
export default {
onLoad() {
this.$onLaunched(() => {
this.data = this.$store.state.data;
});
}
}
3. 使用 main.js 文件:
在 main.js 文件中,可以使用 Vue.prototype.isResolve() 方法判断 onLaunch 函数是否已执行完毕。如果已执行完毕,isResolve() 方法将返回 true,页面可以开始初始化数据。
// main.js
import Vue from 'vue';
Vue.prototype.$isResolve = () => {
return Vue.prototype.$store.state.isLaunched;
};
// Page.vue
export default {
onLoad() {
if (this.$isResolve()) {
this.data = this.$store.state.data;
} else {
this.$onLaunched(() => {
this.data = this.$store.state.data;
});
}
}
}
常见问题解答
1. 为什么会出现异步问题?
因为 JavaScript 的异步执行机制,onLoad 函数可能在 onLaunch 函数返回数据之前执行。
2. 如何使用 await 和 async 解决问题?
在 onLoad 函数中使用 await 关键字等待 onLaunch 函数执行完毕,同时在 onLaunch 函数中使用 async 关键字标记其为异步函数。
3. 什么是 $onLaunched 事件?
$onLaunched 事件是 onLaunch 函数执行完毕时触发的事件,页面可以通过监听该事件来开始数据初始化。
4. 什么是 main.js 文件中的 $isResolve() 方法?
$isResolve() 方法可以判断 onLaunch 函数是否已执行完毕,如果已执行完毕,将返回 true。
5. 如何选择最合适的解决方案?
对于简单的场景,可以使用 await 和 async,对于更复杂的场景,可以使用 onLaunched 事件或 main.js 文件中的 isResolve() 方法。