async函数的使用方式,直接在普通函数前面加上async,表示这是一个异步函数,在要异步执行的语句前面加上await,表示后面的表达式须要等待。async是Generator的语法糖,相比较Generator函数在如下四方面作了改进es6
Generator函数是须要调用next指令来运行异步的语句,async不须要调用next,直接像运行正常的函数那样运行就能够promise
语义化更明确,相比较于Generator的*和yield,async和await更明确。异步
yield命令后面只能是 Thunk 函数或 Promise 对象,而async函数的await命令后面,能够是Promise 对象和原始类型的值(数值、字符串和布尔值,但这时等同于同步操做)。async
async直接返回一个promise对象,能够用then和cache来处理。函数
async function getStockPriceByName(name) { let symbol = await getStockSymbol(name); let price = await getPriceByName(symbol); return price } getStockPriceByName('goog').then( (result)=> { console.log(result); }).catch((err)=>{ console.log(err) })
上面的async异步函数遇到await会先返回一个Promise对象,等到异步操做执行完毕,才会根据结果来执行具体的回调函数。spa
函数声明code
async function foo() {}
表达式声明对象
var bar = async function () {}
对象声明递归
var obj = { async bazfunction(){ } }
箭头函数声明字符串
var fot = async() => { }
await后面是一个promise对象,若是不是,会转成一个resolve的promise对象
async function f() { return await 123; } f().then(function (a) { console.log(a); })
await后面的promise对象,若是reject,则reject参数会被cache参数接收到,写不写return均可以,而且reject下面的代码不会执行,若是想下面的代码执行,必须用try cache包住
async function a() { try{ await Promise.reject('出错了!') }catch (e){ return await Promise.resolve('请从新填写') } } a().then(function () { console.log(err); }).catch(function (err) { console.log(err); })
上面的代码若是不用try cache包裹reject,则下面的代码不会执行,而且reject语句是不用return返回的,resolve语句是须要用return返回;
若是await后面的异步操做出错,那么等同于async函数返回的 Promise 对象被reject。因此一般的处理方法有两种
用try catch包住可能会出错的部分
async function myFunction() { try { await somethingThatReturnsAPromise(); } catch (err) { console.log(err); } }
另外一种写法是对可能要出错的异步操做添加catch回调函数
async function myFunction() { await somethingThatReturnsAPromise().catch((err)=> { console.log(err); }) }
let a=await getFoo(); let b=await getBar();
上面的两个方法都是异步操做,不存在依赖关系,因此咱们能够同时触发,改写成下面的
//第一种写法 let [a,b]=Promise.all([getFoo(),getBar()]) //第二种写法 let aPromise=getFoo(); let bPromise=getBar(); let a=await aPromise; let b=await bPromise;
async函数就是将执行器和Generator作为一个函数返回。
async function fn(){} //等同于 function fn() { return spawn(function* () { }) }
function spawn(genF) { /**** * 返回的是一个promise */ return new Promise(function(resolve, reject) { var gen=genF(); //运行Generator这个方法; /*** * 执行下一步的方法 * @param fn 一个调用Generator方法的next方法 */ function step(fn) { //若是有错误,则直接返回,不执行下面的await try { var next=fn(); }catch (e){ return reject(e) } //若是下面没有yield语句,即Generator的done是true if(next.done){ return resolve(next.value); } // 若是下面还有yield语句,resolve继续执行递归执行gen.next(),reject则抛出错误 Promise.resolve(next.value).then((val)=>{ step(function(){ return gen.next(val) } ) }).catch((e)=>{ step(function(){ return gen.throw(e) } ) }) } step(function () { return gen.next(); }) }); }
参考阮大神的文章:http://es6.ruanyifeng.com/#do...