大宇宇宇
发布于 2025-09-01 / 6 阅读
0
0

async 和 await

Vue 中 asyncawait 是什么?

asyncawait 是 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 })
  })
}


面试回答要点

  1. 核心定义

    "async/await 是 ES2017 引入的异步编程方案,基于 Promise。async 声明函数返回 Promise,await 暂停函数执行直到 Promise 完成。在 Vue 中,它让异步代码(如 API 请求)更易读、易维护。"

  2. 关键优势

    • 可读性:避免 .then() 链式调用,代码结构清晰。

    • 错误处理:通过 try/catch 统一捕获异常,比 Promise 的 .catch() 更直观。

    • 调试友好:异步代码像同步代码一样可设置断点调试。

  3. Vue 特有场景

    "在 Vue 中,async/await 主要用于:

    • 生命周期钩子(如 created/mounted)加载数据;

    • 路由守卫中的权限校验;

    • Vuex Actions 处理异步请求;

    • 表单提交等用户交互场景。"

  4. 对比 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);
    ```"
  5. 注意事项

    • await 必须在 async 函数内使用;

    • 并发请求需用 Promise.all()(如 await Promise.all([req1, req2]));

    • 错误处理必须用 try/catch,否则未捕获的 Promise 错误会静默失败。


总结

在 Vue 中,async/await 是处理异步操作的标准实践,适用于数据加载、路由守卫、状态管理等场景。它通过同步风格的代码提升可维护性,是面试中考察异步编程能力的关键点。回答时需结合 Vue 特定场景(如生命周期、Vuex),并强调其相比传统回调或 Promise 链的优势。


评论