vue-element-admin中:const { roles } = await store.dispatch('user/getInfo')
async 函数返回一个 Promise 对象
async
函数内部 return 返回的值。会成为 then
方法回调函数的参数。
async function f() {
return
'hello world'
};
f().then( (v) => console.log(v))
// hello world
如果 async
函数内部抛出异常,则会导致返回的 Promise 对象状态变为 reject
状态。抛出的错误而会被 catch
方法回调函数接收到。
async function e(){ throw new Error('error'); } e().then(v => console.log(v)) .catch( e => console.log(e));
async 函数返回的 Promise 对象,必须等到内部所有的 await 命令的 Promise 对象执行完,才会发生状态改变
也就是说,只有当 async
函数内部的异步操作都执行完,才会执行 then
方法的回调。
const delay = timeout => new Promise(resolve=> setTimeout(resolve, timeout)); async function f(){ await delay(1000); await delay(2000); await delay(3000); return 'done'; } f().then(v => console.log(v)); // 等待6s后才输出 'done'
正常情况下,await 命令后面跟着的是 Promise ,如果不是的话,也会被转换成一个 立即 resolve 的 Promise
如下面这个例子:
async function f() { return await 1 }; f().then( (v) => console.log(v)) // 1
如果返回的是 reject 的状态,则会被 catch
方法捕获。
async 函数的语法不难,难在错误处理上。 先来看下面的例子:
let a; async function f() { await Promise.reject('error'); a = await 1; // 这段 await 并没有执行 } f().then(v => console.log(a)); 如上面所示,当 async 函数中只要一个 await 出现 reject 状态,则后面的 await 都不会被执行。 解决办法:可以添加 try/catch。 // 正确的写法 let a; async function correct() { try { await Promise.reject('error') } catch (error) { console.log(error); } a = await 1; return a; } correct().then(v => console.log(a)); // 1
如果有多个 await 则可以将其都放在 try/catch 中。
./permission.js
import router from './router' import store from './store' import { Message } from 'element-ui' import NProgress from 'nprogress' // progress bar import 'nprogress/nprogress.css' // progress bar style import { getToken } from '@/utils/auth' // get token from cookie import getPageTitle from '@/utils/get-page-title' NProgress.configure({ showSpinner: false }) // NProgress Configuration const whiteList = ['/login', '/auth-redirect'] // no redirect whitelist router.beforeEach(async(to, from, next) => { // start progress bar console.log(to) NProgress.start() // set page title document.title = getPageTitle(to.meta.title) // determine whether the user has logged in const hasToken = getToken() if (hasToken) { if (to.path === '/login') { // if is logged in, redirect to the home page next({ path: '/' }) NProgress.done() // hack: https://github.com/PanJiaChen/vue-element-admin/pull/2939 } else { // determine whether the user has obtained his permission roles through getInfo const hasRoles = store.getters.roles && store.getters.roles.length > 0 if (hasRoles) { next() } else { try { // get user info // note: roles must be a object array! such as: ['admin'] or ,['developer','editor'] const { roles } = await store.dispatch('user/getInfo') // generate accessible routes map based on roles const accessRoutes = await store.dispatch('permission/generateRoutes', roles) // dynamically add accessible routes router.addRoutes(accessRoutes) // hack method to ensure that addRoutes is complete // set the replace: true, so the navigation will not leave a history record next({ ...to, replace: true }) } catch (error) { // remove token and go to login page to re-login await store.dispatch('user/resetToken') Message.error(error || 'Has Error') next(`/login?redirect=${to.path}`) NProgress.done() } } } } else { /* has no token*/ if (whiteList.indexOf(to.path) !== -1) { // in the free login whitelist, go directly next() } else { // other pages that do not have permission to access are redirected to the login page. next(`/login?redirect=${to.path}`) NProgress.done() } } }) router.afterEach(() => { // finish progress bar NProgress.done() })