Vue 中 async 和 await 是什么?
async 和 await 是 JavaScript 中用于处理异步操作的关键字(基于 Promise),在 Vue 中主要用于简化异步代码的编写:
async:声明一个函数为异步函数,自动将其返回值包装为 Promise。await:暂停异步函数执行,等待 Promise 完成(成功/失败),只能在async函数内部使用。
核心作用:将异步代码(如 API 请求、定时器)写成类似同步的线性结构,避免回调地狱(Callback Hell),提升可读性。
应用场景(Vue 特定)
1. 生命周期钩子中获取数据
场景:组件创建时异步加载数据(如 API 请求)。
示例:
export default { async created() { try { const res = await axios.get('/api/user'); this.userData = res.data; } catch (error) { console.error('数据加载失败:', error); } } }
2. 表单提交与验证
场景:提交表单前等待异步验证(如用户名查重)。
示例:
methods: { async submitForm() { const isValid = await this.validateForm(); // 异步验证 if (isValid) { await axios.post('/api/submit', this.formData); this.$router.push('/success'); } } }
3. 路由导航守卫
场景:进入路由前异步检查用户权限或预加载数据。
示例:
const router = new VueRouter({ routes: [...] }); router.beforeEach(async (to, from, next) => { if (to.meta.requiresAuth) { const isAuthenticated = await checkAuth(); // 异步鉴权 isAuthenticated ? next() : next('/login'); } else { next(); } });
4. Vuex Actions 异步操作
场景:在 Vuex 中处理异步逻辑(如 API 请求)后提交 mutation。
示例:
actions: { async fetchUser({ commit }) { const res = await axios.get('/api/user'); commit('SET_USER', res.data); // 提交 mutation } }
5. 组合式 API(Vue 3)
场景:在
setup()或组合式函数中处理异步逻辑。示例:
import { ref, onMounted } from 'vue';
export default {
setup() {
const data = ref(null);
onMounted(async () => {
data.value = await fetchData(); // 异步获取数据
});
return { data };
}
}用户登录后获取用户数据
业务逻辑:
调用用户登录接口,返回 token
调用获取用户信息接口,携带 token,返回 userInfo
这里的逻辑很简单,存在一个排队的情况,用 async/await 实现再适合不过了
伪代码:
const login = async () => {
const loginRes = await loginAPI()
// loginAPI接口返回的token会存入localStorage,作为默认参数传递
// 因此getUSerInfo不用手动传token
const userInfoRes = await getUserInfo()
}图片上传
业务逻辑:
通过 FormData 格式传输图片,返回图片 url
在某表单提交的接口上传表单数据,携带 url
跟上个情景类似,但这边还存在批量图片上传的情况,这里可以使用 Promise.all,这里解释一下这样使用的优缺点:
优点:不用排队,图片批量上传速度快
缺点:任何一个请求失败,返回 reject(ps:可以用 Promise.allSettled 解决问题)
伪代码:
const filePromsie = (file) => {
const formdata = new FormData()
formdata.append(file)
return fileSubmitAPI(formdata)
}
const submit = (files) => {
const promiseArr = []
files.length && files.forEach((file) => {
promiseArr.push(filePromsie(file))
})
Promise.all(promiseArr).then((res) => {
tableSubmitAPI({ res, ...tableData })
})
}面试回答要点
核心定义
"
async/await是 ES2017 引入的异步编程方案,基于 Promise。async声明函数返回 Promise,await暂停函数执行直到 Promise 完成。在 Vue 中,它让异步代码(如 API 请求)更易读、易维护。"关键优势
可读性:避免
.then()链式调用,代码结构清晰。错误处理:通过
try/catch统一捕获异常,比 Promise 的.catch()更直观。调试友好:异步代码像同步代码一样可设置断点调试。
Vue 特有场景
"在 Vue 中,
async/await主要用于:生命周期钩子(如
created/mounted)加载数据;路由守卫中的权限校验;
Vuex Actions 处理异步请求;
表单提交等用户交互场景。"
对比 Promise
"虽然 Promise 也能处理异步,但
async/await避免了回调嵌套,尤其在连续异步操作时优势明显。例如:// Promise 链式调用 fetchA().then(a => fetchB(a).then(b => console.log(a, b))); // async/await const a = await fetchA(); const b = await fetchB(a); console.log(a, b); ```"注意事项
await必须在async函数内使用;并发请求需用
Promise.all()(如await Promise.all([req1, req2]));错误处理必须用
try/catch,否则未捕获的 Promise 错误会静默失败。
总结
在 Vue 中,async/await 是处理异步操作的标准实践,适用于数据加载、路由守卫、状态管理等场景。它通过同步风格的代码提升可维护性,是面试中考察异步编程能力的关键点。回答时需结合 Vue 特定场景(如生命周期、Vuex),并强调其相比传统回调或 Promise 链的优势。