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。