async函数 -->Generator函数的语法糖
(1) async函数将Generator函数的 * 替换成 async,将yield 替换成 await
....//
const gen = function* (){
const f1 = yield readFile('/ect/fstab');
const f2 = yield readFile('/ect/shells');
console.log(f1.toString());
console.log(f2.toString());
}
//写法等同下面
const asyncReadFile = async function(){
const f1 = await readFile('/ect/shells');
const f2 = await readFile('/ect/shells');
console.log(f1.toString());
console.log(f2.toString());
}
(2) async函数对Generator函数的改进:
a.内置执行器
Generator函数需要依靠co模块或调用next方法来支持函数的执行,而async函数自带执行器
b.更好的语义
async表示函数里有异步操作
await表示紧跟在后面的表达式需要等待结果
c.更广的适用性
co模块约定,yield命令后面只能是Thunk函数或Promise对象
async函数的await命令后面可以是Promise对象和原始类型的值(数值、字符串和布尔值,会自动转成立即resolved的Promise对象)
d.返回值是Promise
async函数的返回值是Promise对象,可以用then方法指定下一步的操作
(3) 基本用法
async函数执行时,一遇到await就会先返回,直至异步操作完成,Promise对象才会发生状态改变,除非遇到return语句或直接抛出错误,只有异步执行完后,才会接着执行函数体内后面的语句
(4) async函数多种使用形式
函数声明
async function (){}
函数表达式
const foo = async function () {}
对象的方法
let obj = { async foo () {} };
obj.foo().then(...)
Class的方法
class Storage {
constructor() {
this.cachePromise = caches.open('avatars');
}
async getAvatar(name) {
const cache = await this.cachePromise;
return cache.match(`/avatars/${name}.jpg`);
}
}
const stroage = new Stroage ();
stroage.getAvatar('jake').then(...);
箭头函数
const foo = async () => {};
(5)语法
a.async函数返回一个Promise对象
b.async函数内部 return 语句返回的值会成为 then 方法回调函数的参数
async函数内部抛出错误,会导致返回的Promise对象变为reject状态,抛出的错误对象会被catch方法回调函数接收到;任何一个await语句后面的Promise对象状态为reject状态,那么整个async函数都会中断进行
倘若想要一个异步操作失败后不要中断后面的异步操作,则需把第一个await放在try…catch结构里面,或者await后面的Promise对象再跟一个catch方法
//将await放入tey...catch结构内
async function f() {
try {
await Promise.reject('出错了');
}catch(e) {
}
return await Promise.resolve('Hello world');
}
f().then(v => console.log(v))
//Hello world
(6)await命令
a.倘若await命令后面不是一个Promise对象,那么则直接返回对应的值
b.若await命令后面是一个 thenable对象(定义了then方法的对象),那么await会将其等同于Promise对象
(7)注意
如果希望多个请求并发执行,不存在继发关系的话,可以使用Promise.all方法,这样的配置会更清晰,缩短程序执行时间
await命令只能在async函数之中使用
最好把await放在try…catch更好,不会影响后续想要执行的"销售雇员"字段