async/await作为ES7的标准被视作javascript异步函数操作的终极解决方案(超越Promise和Generator)越来越受到重视,而随着前端构建工具的蓬勃发展,通过配置babel我们在项目中也可以直接使用这一新特性而无需太过在意浏览器的兼容性问题。
有很多技术博客对这两个概念有非常棒的阐述,我之所以自己再写一篇主要是为了笔下走一遍加深理解同时方便以后翻看。也是因为最近在做的一件事情,是将我们Angular4 + Typescript项目中的Promise操作全部替换为async/await。借着这个机会把这两个关键字用一个最简单的例子再总结一下。
MDN async
MDN await
定义
调用async函数时会返回一个Promise对象。当这个async函数返回一个值时,Promise的resolve方法会负责传递这个值;当async函数抛出异常时,Promise 的 reject 方法也会传递这个异常值。
async函数中可能会有await表达式,这会使async函数暂停执行,等待表达式中的 Promise 解析完成后继续执行async函数并返回解决结果。
async/await的目的是在promises的基础上进一步简化异步的同步调用,它能对一组Promises执行一些操作。正如Promises类似于结构化回调,async/await类似于组合生成器和promises。
总结
上面是官网的相关描述,从这里可以提炼出以下几个关键点:
-async/await 本质上依然是基于Promise,但在使用上更加简便符合自然习惯。
-async函数内部同步执行。await之间相当于.then。
-async函数外部的调用异步执行。
-需要try/catch await应对promise reject的情况。
栗子
下面是一个简单的例子涵盖上面总结的四点:
function resolveAfter2Seconds(x) {return new Promise(resolve => {setTimeout(() => {resolve(x);}, 2000);});}function resolveInPromiseRightNow(x) {return new Promise(resolve => {resolve('data from previous await: ' + x);});}return new Promise((resolve, reject) => {reject('reject' );});}function fn1() {console.log('normal function');}// await只能在async函数中执行并且在async中是阻塞的async function asyncFunction() {var x = await resolveAfter2Seconds('resolve after 2s');console.log(x); console.log('message between 2 await');var y = await resolveInPromiseRightNow(x);console.log(y);try {await rejectInPromise();} catch(ex) {console.log(ex);}}// .then说明Promise本质asyncFunction().then(() => {console.log('await completed');});fn1(); /// 结果// normal function/// 2s后// resolve after 2s// message between 2 await// data from previous await: resolve after 2s// reject// await completed