1》概念:是Generator函数的语法糖吗,它的实现原理就是将Generator函数和自动执行器,包在一个函数里。
返回一个promise对象,可以使用then方法添加回调函数,当函数执行时,一旦遇到await就先返回,等到异步操作完成,再接着执行函数体内后面的语句
2》async函数多种使用形式
函数声明
async function foo(){}
函数表达式
const foo=async function(){}
对象的方法
let obj={async foo(){}};
obj.foo().then();
箭头函数
const foo=async ()=>{};
class方法
class Storage{
constructor(){}
async getAvatar(name){}
}
const storage=new Storage();
storage.getAvatar().then()
3》语法
3.1>返回promise对象
async函数内部return语句返回的值,会成为then方法回调函数的参数
async函数内部抛出错误,会导致返回的promise对象变成reject状态,抛出的错误对象会被catch方法回调函数接收到
async函数返回的promise对象,必须等到内部所有的await命令后面的promise对象执行完,才会发生状态改变,除非遇到return语句或者抛出错误,也就是说只有async函数内部异步操作执行完,才会执行then方法
指定的回调函数
3.2>await命令
await等待的是一个表达式,这个表达式的返回值可以是一个promise对象也可以是其他值,如果等到的是promise对象,await就忙起来他会阻塞后面的代码,等到promise.resolve()的值作为await表达式的运算结果,这也是await必须在async函数中的原因,async函数调用不会造成阻塞,它内部所有的阻塞都被封装在一个promise对象中异步
3.21》一般,await命令后面是一个promise对象,如果不是,会被转成一个立即resolve的promise对象
3.22》await命令后面的promise对象变成reject状态,则reject的参数会被catch方法的回调函数接受到,并且整个async函数都会中断
如果希望前一个异步操作失败,也不要中断后面的异步操作,方法:
方法一:那么可以将await放在try..catch结构中
方法二:await后面的promise对象再跟一个catch方法
3.23》多个await命令后面的异步操作,如果不存在继发关系最好让他们同时触发,方法
方法一:let [foo,bar]=await Promise.all([getfoo(),getbar()])
方法二: let foopromise=getfoo();
let barpromise=getbar();
let foo=await foopromise;
let foo=await barpromise;
3.24》await命令只能用在async函数之中,用在普通函数之中会报错
3.3>与其他异步方法的比较(async,promise,Generator)
promise操作本身的语义不易看出
Generator语义比promise清晰,必须有一个任务执行器自动执行Generator函数
async最符合语义,将Generator写法中的自动执行器改在语言层提供,不暴露给用户