async和await

async 函数的返回值始终是一个 Promise 对象。

async function example1() {
  return 'Hello, world!';
}

example1().then(result => {
  console.log(result); // 输出: Hello, world!
});

在这个示例中,example1 函数返回字符串 ‘Hello, world!’,但是由于它是一个 async 函数,这个返回值会被封装在一个解决的 Promise 中。

  • 没有返回值:async 函数返回一个resolved的 Promise,其值为 undefined。
  • 有返回值:async 函数返回一个resolved的 Promise,其值为返回的值
  • 抛出错误:async 函数返回一个rejected的 Promise,其错误为抛出的错误。
// 批量删除
async deleteBatch () {
  await this.deleteContent(this.multipleSelection);
  console.log("1");
},
// 单个删除
async deleteContent (id) {
  MessageBox.confirm('您确定删除', '删除', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(async () => {
    const response = await deleteUser({ ids: id.toString() });
    Message({
      message: '删除成功',
      type: 'success',
      duration: 3 * 1000
    });
    this.init();
  })
}

在上面的代码中,批量删除时,await失效,直接打印“1”,由于在执行 deleteContent函数时,MessageBox.confirm 是一个异步函数,并且没有等待其执行完毕,就直接结束了deleteContent函数,函数会返回一个值为undefined的Promise。
控制台报错Uncaught (in promise) cancel,是因为点击cancel时,MessageBox.confirm 会返回一个 Promise,当用户确认或取消时,该 Promise 会解决或拒绝。如果用户取消,Promise 会被拒绝,需要catch接收。
正确代码:

async deleteBatch () {
  await this.deleteContent(this.multipleSelection)
  console.log("1");
},
// 单个删除
async deleteContent (id) {
  await MessageBox.confirm('您确定删除', '删除', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    }).then(async () => {
      const response = await deleteUser({ ids: id.toString() });
      Message({
        message: '删除成功',
        type: 'success',
        duration: 3 * 1000
      });
      this.init();
    }).catch(error => {
      // 用户取消操作,不做任何处理
    })

MessageBox.confirm 是一个异步函数,在嵌套的函数中,也需要await等待执行完毕,再接着执行。

拓展

1.在方法中需要调用,函数返回的结果后,在继续下一步,await发现不生效,原因如下:

async和await ,这个await只有在他等待的函数返回的是Promise的时候才会生效,所以异步操作必须包含Promise里面。

解决方法:不生效时,考虑await的方法是否返回的是Promise,若不是,用Promise包装即可。

2.其他不生效的原因需要具体情况具体分析,如:

map/forEach中await一个返回的Promise的函数依然不生效,原因map/forEach内部使用了while结合callback方式来执行函数,await不会等待callback的执行。

解决方法:改用for循环,或者在map/forEach外,用promise.all()包装。

3.无论响应拦截器返回什么类型的值,最终在使用 Axios 时,所有的处理结果都会以 Promise 的形式呈现。

Axios 是一个基于 Promise 的 HTTP 库,Axios返回的就是一个promise对象。
axios拦截器执行顺序
async和await

在 JavaScript 中,任务队列机制分为三类:同步任务、微任务(microtasks)和宏任务(macrotasks)。理解这些任务类型及其执行顺序是掌握 JavaScript 异步编程和事件循环的关键。

  • 同步任务
    同步任务是立即执行的任务,在执行栈中按照顺序依次执行。所有同步任务都会在任何异步任务之前执行。

  • 微任务
    微任务是一种异步任务,但它的执行优先级高于宏任务。微任务会在当前事件循环结束后,立即执行。常见的微任务包括:
    a. Promise.then 和 Promise.catch 回调
    b. MutationObserver 回调
    c. queueMicrotask

  • 宏任务
    宏任务也是一种异步任务,但它的执行优先级低于微任务。宏任务通常包括:
    a. setTimeout
    b. setInterval
    c. setImmediate(仅在 Node.js 环境中)
    d. I/O 任务
    e. UI 渲染任务

  • 事件循环
    事件循环负责协调同步任务、微任务和宏任务的执行顺序:
    a. 同步任务:所有同步任务都在主线程上按顺序执行,直到执行栈为空。
    b. 微任务队列:执行栈清空后,立即执行微任务队列中的所有任务,直到微任务队列为空。
    c. 宏任务队列:当微任务队列为空时,从宏任务队列中取出一个任务并执行,然后进入下一轮事件循环。

在这里插入图片描述

init开始
定时器开始
init结束
定时器ing
定时器结束

上面的代码执行结果如上,init函数如果需要showdialog执行结束再“init结束”,则仍旧需要加async和await,因为showdialog中的awiat只能限制该作用域的,对init函数中的init结束来说,没有限制,仍旧是同步代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值