(自用面试题)async/await是什么?

75 阅读2分钟

async/await的定义

async/await是Generator函数的语法糖,async表示函数里有异步操作,  await表示紧跟在后面的表达式需要等待结果。
它能实现的效果都能用then链来实现,它是为优化then链而开发出来的。

async/await的使用

  • async函数返回一个Promise对象,可以使用then方法添加回调函数。async函数内部return语句返回的值, 会成为then方法回调函数的参数。

eg:

async function f() {   
  return 'hello world'; 
} 
f().then(v => console.log(v)) // "hello world"

上面代码中, 函数f内部return命令返回的值, 会被then方法回调函数接收到。

  • async函数返回的Promise对象, 必须等到内部所有await命令后面的Promise对象执行完, 才会发生状态改变, 除非遇到return语句或者抛出错误。也就是说, 只有async函数内部的异步操作执行完, 才会执行then方法指定的回调函数。

eg:

async function getTitle(url) {   
  let response = await fetch(url);   
  let html = await response.text();   
  return html.match(/<title>([\s\S]+)<\/title>/i)[1]; 
} 
getTitle('https://tc39.github.io/ecma262/').then(console.log// "ECMAScript 2017 Language Specification"

上面代码中, 函数getTitle内部有三个操作: 抓取网页、取出文本、匹配页面标题。只有这三个操作全部完成, 才会执行then方法里面的console.log。

  • 正常情况下,await命令后面是一个Promise对象。如果不是, 会被转成一个立即resolve的Promise对象。

eg:

async function f() {     
  return await 123;   
}   
f().then(v => console.log(v)) // 123  

上面代码中,await命令的参数是数值123,它被转成Promise对象,并立即resolve。

  • await命令后面的Promise对象如果变为reject状态,则reject的参数会被catch方法的回调函数接收到。

eg:

async function f() {   
await Promise.reject('出错了'); 
} 
f() 
.then(v => console.log(v)) 
.catch(e => console.log(e)) // 出错了

上面代码中,await语句前面没有return,但是reject方法的参数依然传入了catch方法的回调函数。这里如果在await前面加上return,效果是一样的。

  • 只要一个await语句后面的Promise变为reject,那么整个async函数都会中断执行。

eg:

async function f() {   
  await Promise.reject('出错了');   
  await Promise.resolve('hello world'); // 不会执行
}

上面代码中,第二个await语句是不会执行的,因为第一个await语句状态变成了reject。