每天集中精力学一会ES6,效果还是蛮好的,嗯,跟着阮一峰大神学功夫喽,如果你也见识见识阮一峰大神的神功,请点击http://es6.ruanyifeng.com/#docs/async
async函数的写法和语法:
1、async函数就是将Generator函数的星号替换成async,将yield替换成await
2、async函数返回一个Promise对象,可以使用then方法添加回调函数。当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体后面的语句。
const Genera = function * (){
yield .....
}
const asy = async function (){
const a = ...
}
async函数对Generator函数的改进。
- 内置执行器:Generator函数的执行必须靠执行器,而async函数自带执行器,async函数的执行,与普通函数一模一样
- 更好的语义:async和await,比起星号和yield,语义更清楚了。async表示函数里有异步操作,await 表示紧跟在后面的表达式需要等待结果。
- 适用性更广:co模块约定,yield命令后面只能是Thunk函数或Promise对象,而async函数的await命令后面,可以是Promise对象和原始类型(数值、字符串和布尔值,但这时等同于同步操作)
- 返回值是Promise对象:比Generator函数的返回值是Iiterator对象方便多了。可以用then方法指定下一步的操作。
async函数的语法:
async函数返回一个Promise对象,async函数内部return语句返回的值,会成为then方法回调函数的参数。
async function fn(){
return "donna";
}
fn().then(f=>console.log(f));//donna
async函数内部抛出错误,会导致返回的Promise对象变为reject状态,抛出的错误对象会被catch方法回调函数接收到。
async function fn(){
throw new Error("错了错了")
}
fn().then(f=>console.log(f),e=>console.log(e));//Error: 错了错了
async函数返回的Promise对象,必须等到内部所有await命令后面的Promise对象执行完毕,才会发生状态改变,除非遇到return语句或者抛出错误,也就是说,只有async函数内部的异步操作执行完,才会执行then方法指定的回调函数。
await命令:
正常情况下,await命令后面是一个Promise对象,如果不是会被转成一个立即resolve的Promise对象。
async function f() {
return await 123;
}
f().then(v => console.log(v));//123
async function f() {
return await new Promise(resolve=>{
resolve("leo");
})
}
f().then(v => console.log(v));//leo
await命令后面的Promise对象如果变为reject状态,则reject的参数会被catch方法的回调函数接收到
注意:只要一个await语句后面的Promise变为reject,那么整个async函数都会中断执行(不论await函数前面是否有return,结果都一样)。
async function fn(){
await Promise.reject("错了");
return await 123;
}
fn().then(v=>console.log(v),e=>console.log(e));//错了
错误处理:我们知道如果await后面的异步操作出错,那么等同于async函数返回的Promise对象被reject
所以比较好的办法1、是将await命令放在try…catch代码块中。2、await后面的Promise对象再跟一个catch方法,处理前面可能出现的错误。
使用注意点:
我们知道await命令后面的Promise对象,运行结果可能是rejected,所以最好把await命令放在try…catch代码块中。
多个await命令后面的异步操作,如果不存在继发关系,最好让他们同时触发
await命令只能用在async函数之中,如果用在普通函数,就会报错。