最近遇到了一个问题:在 App.vue 中的 onLaunch
中调用登录接口时,由于异步登录尚未完成就调用了 index 页面的接口,导致 token 异常。如何确保页面在 App
中的 onLaunch
执行完毕后再继续执行呢? 在网上查阅了一些资料,发现大多数解决方案涉及登录状态设置、页面通过轮询或消息通知等方式等待状态,这些方法都不太理想。
解决方案:
要确保在App.vue中的onLaunch调用登录接口完成后再调用index的其他接口,可以使用 Promise 来控制异步操作的执行顺序
1、在App.vue中,使用Promise封装登录接口的调用,并在登录成功后返回一个resolve。
javascript
export default {
onLaunch() {
// 封装登录接口为一个Promise
const loginPromise = new Promise((resolve, reject) => {
// 调用登录接口
loginFunction().then(() => {
// 登录成功时,执行 resolve
resolve();
}).catch((error) => {
// 登录失败时,执行 reject
reject(error);
});
});
// 将 loginPromise 作为一个全局变量
this.globalData.loginPromise = loginPromise;
}
}
2、在index页面中,在页面加载时,通过调用登录接口的Promise,等待登录接口成功后再调用其他接口。
javascript
export default {
onLoad() {
// 获取 App 实例
const appInstance = getApp();
// 等待登录接口的Promise完成后,再调用其他接口
appInstance.globalData.loginPromise.then(() => {
// 调用 index 页面的接口
getIndexInfo().then((res) => {
// 处理其他接口的结果
}).catch((error) => {
// 错误处理
});
}).catch((error) => {
// 登录失败处理
});
}
}
测试通过完工 ~
可能有同学会有疑问,每次获取loginPromise的时候会不会每次都登录?
答案是不会的,App.vue
中的 loginPromise
是在 onLaunch
生命周期钩子中创建的 Promise 对象,该 Promise 对象只会在应用初始化时调用一次登录接口,并在登录成功后 resolve
。之后,其他页面获取 loginPromise
时并不会触发再次登录,而是直接返回之前创建好的 Promise 对象。
这意味着,每次获取 loginPromise
时不会导致重复登录,而是仅返回之前创建好的 Promise 对象。这种方式确保了登录操作只会在应用启动时执行一次,避免了重复登录