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() })