关于router.beforeEach 调用 axios 的问题

关于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

回到顶部