async函数【ES6】
2019-03-28
async函数【ES6】
async函数是Generator和Promise结合的语法糖,具体来说就是将Generator函数的*
声明符换为async
,将yield
换为await
。关于Generator函数可以看我的另外一篇文章。
这样做会有如下效果:
-
内置执行器
一个async函数会一直执行到结束,输出最终结果,而不像Generator需要自己写执行器。
-
返回值是
Promise
async函数的
return
返回值用Promise对象进行了包装,用Promise的语法来执行下一步操作 -
将多个Promise组合成一个串行函数
await操作符后是一个Promise对象,如果不是,会被转换成一个已经resolve的Promise对象。当遇到一个await表示式时会立即返回,等待await后的Promise内部逻辑结束后继续执行。
语法
function asyncWait() {
return new Promise((resolve)=>{
setTimeout(resolve,1000);
})
}
async function f() {
await asyncWait();
await asyncWait();
return "over"
}
f().then(data=>console.log(data));
- 通过
async
关键字声明async函数 - await操作符后跟Promise对象
- return的值自动用Promise包装
- 像Generator的yield一样,async执行到await表达式会停止执行,但是重新开始状态变化是等到await后的Promise执行完自动开始。
错误处理
async函数的语法导致其错误处理比较复杂,当await后的Promise执行中抛出错误(指调用全局throw
),或调用reject,将会用Promise的错误处理机制来处理错误。
async function f(){
await new Promise((resolve)=>{throw new Error('出错')});
}
//等价写法
async function f(){
await new Promise((resolve,reject)=>{reject('出错')});
}
try{
f().then(v=>console.log('继续执行'+v))
.catch((e=>console.log('发生错误'+e)));
}catch(e){
console.log('抓不到错误'+e);
}
// 发生错误Error: 出错
和其他异步方法的关系
ES6添加的三个主要的异步方法即:Promise
, Generator
, Async
,个人对这三个方法区别的看法是:
- Promise: 以对象链式调用的方法处理异步逻辑;
- Generator: 状态机,本身不是用来专门用于异步逻辑,需要外部执行器处理异步逻辑;
- async: 以状态机的方式自动处理异步逻辑,不需要外部处理器,内部用到了Promise来实现;