async await

async作为一个关键字放在函数前面,表明这是一个异步函数。await,等待,后面可以跟任何表达式,但一般跟一个返回promise对象的表达式。await关键字必须放在async函数里面。

async函数的返回值

  1. 如果async函数中有返回值,会调用Promise.resolve()包装后作为返回值。
  2. 如果返回值恰好是一个promise对象,则会返回一个pending状态的promise对象。
  3. 如果函数中没有返回值,则返回Promise.resolve(undefined)。
  4. 如果函数中有await或其他异步语句,函数没执行完,怎么知道有没有返回值呢,所有返回一个pending状态的promise对象。
  5. 如果函数内部抛出错误,则会调用Promise.reject()返回一个promise对象。
  async function test() {
    return 'hello'
  }
  async function test1() {
    return Promise.resolve('world')
  }
  async function test2() {
    let a = 2
    await ++a
    return a
  }
  async function resu() {
    let res = test()
    let res1 = test1()
    let res2 = test2()
    console.log(res)
    console.log(res1)
    console.log(res2)
  }
  resu()

结果:
在这里插入图片描述

加了await的返回值

  async function test() {
    return 'hello'
  }
  async function test1() {
    return Promise.resolve('world')
  }
  async function test2() {
    let a = 2
    await ++a
    return a
  }
  async function resu() {
    let res = await test()
    let res1 = await test1()
    let res2 = await test2()
    console.log(res)
    console.log(res1)
    console.log(res2)
  }
  resu()

相对于上面那个例子,只是加了个await。查看结果:
在这里插入图片描述
这个怎么理解呢?
因为赋值语句是立即执行的,async函数虽然可能里面都是同步语句,但这个函数是异步的,所有语句执行完后,你可以当做这个函数没有执行完,所以赋值的是一个promise对象。加上await之后,等待异步函数执行完之后,再执行赋值语句,该返回啥就返回啥嘛。

我们不使用await,在async函数执行完之后,再进行赋值语句,看等于啥。

  async function test() {
    return 'thanks'
  }
  let a = test()
  console.log(a)
  new Promise((resolve, reject) => {
    resolve(test())
  }).then(b => {
    console.log(b)
  })

我们来看看结果:
在这里插入图片描述
历史总是惊人的相似!

async await执行顺序——让出线程?
await后面如果接的是同步语句,则会立即执行,然后让出当前线程;await后面如果接的是异步语句,则会将其加入队列,然后让出当前线程。
但是让出线程后,什么时候回来执行后面的代码呢?-_- !
先让我们看一个例子:

  async function test1() {
    await console.log('test1')
    console.log(111)
  }
  async function test2() {
    await Promise.resolve().then(() => {
      console.log('test2')
    })
    console.log(222)
  }
  async function test3() {
    await setTimeout(() => {
      console.log('test3')
    }, 0)
    console.log(333)
  }
  setTimeout(() => {
    console.log('宏任务开始')
  }, 0)
  Promise.resolve().then(() => {
    console.log('微任务开始')
  })
  test1()
  test2()
  test2()
  test3()
  Promise.resolve().then(() => {
    console.log('微任务结束')
  })
  setTimeout(() => {
    console.log('宏任务结束')
  }, 0)

结果:
在这里插入图片描述
可以看到,await后面跟一个setTimeout()并没有什么作用。所有还是开头那句话,await后面一般跟一个可以返回promise对象的表达式。如果await后面跟的是一个可以返回promise对象的表达式,则会等它执行完后,再将后面的代码加入到微任务中;否则,立即将后面的代码加入到微任务中。

await后面的promise对象状态可能是rejected,所以最好把await放在try…catch中。

  async function test() {
    try {
      await dosomething()
    } catch (err) {
      console.log(err)
    }
  }
  test().then(f1, f2)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值