关于router.beforeEach 调用 axios 的问题
现在我有一个需求在所有页面,显示前需要做一个远程的授权验证
我用router + axios 来做的,这个代码在执行的过程中:
check()
第一次没有执行axios代码
所有代码都走完,才会走axios的代码
难到是执行顺序不吗?
但我加了await 正常不是应该 check()一次性全走完的嘛
不知道哪里写错了
router/index.js
import Router from 'vue-router'import HelloWorld from '@/components/HelloWorld'
import check from '../js/check'
Vue.use(Router)
const router = new Router({
routes: [
{
path: '/',
name: 'HelloWorld',
component: HelloWorld
}
]
})
router.beforeEach((to, from, next) => {
alert('123')
alert(check()) ----->show msg is [object:promise]
})
export default router
http://test.com/name=123 1
return msg
{ "status": 0,
"msg": "ok",
"data": null
}
js/check.js
import axios from 'axios'let Url = 'http://test.com.cn/name=123'
export default async function check () {
let aa
await axios.get(Url)
.then(function (response) {
aa = response.data
console.log(response)
})
.catch(function (error) {
console.log(error)
})
return aa
}
回答:
Vue Router 的 beforeEach 的参数是一个 NavigationGuard 类型的参数,这是一个函数,允许三个参数。其中最后一个 next
参数主要用于完成之后的回调(异步操作完成之后调用),它也允许返回一个 Promise 来代替 next
(具体看 NavigationGuard 的文档)。
axios 是一个异步过程,在没有进行异步等待的时候,它会在下一句代码之后才完成。也就是:
router.beforeEach((to, from, next) => { alert('123')
alert(check()) // 这里 check() 还没完成
// 就已经执行到 alert 了,因为 check 是一个异步过程
// 所以 alert 看到的是一个 Promise 对象
})
check()
是一个 async 函数,所以一定会返回一个 Promise,如果要在 Promise 完成之后再进行操作,可以在其对象的 .then()
中处理,也可以使用 await
来异步等待。但要注意的是 await
需要在 async
函数中使用。所以
router.beforeEach((to, from, next) => { alert('123')
check().then((res) => {
alert(res);
next(true); // 这里调用 next 表示异步操作完成,继续后续过程
}); // 注意,没有处理 reject 的情况,所以异步逻辑是不完整的(分支非完全覆盖)
})
不使用 next
,可以返回 Promise 链的结果。但要注意,任何分支的最后一个 Promise 应该包裹一个 boolean 值
return check() .then((res) => {
// 处理 res
return true; // 和 next(true) 等效
})
.catch(() => {
// 处理出错的情况
return false; // 和 next(false) 等效
})
可以使用 await
router.beforeEach(async (to, from, next) => { alert('123');
try {
const res = await checl();
// 使用 res
return true;
} catch (err) {
// 处理错误
return false;
}
})
参考阅读:
- 异步编程需要“意识”
- 理解 JavaScript 的 async/await
补充一下,check()
内部的处理还可以优化一下
import axios from "axios";let url = "http://test.com.cn/name=123";
export default async function check() {
const response = await axios.get(url)
// 避免使用 try ... catch 包裹,使用 .catch() 把异常处理成正常的数据
// 这里没有返回,也就是 return undefiend;
.catch(err => {
console.log(err);
});
// response 不存在(被 catch 处理过)时返回 undefined
// 存在时返回其 data 属性值
return response?.data;
}
以上是 关于router.beforeEach 调用 axios 的问题 的全部内容, 来源链接: utcz.com/p/937040.html