锋利的ES6 — Async Await
锋利的ES6 系列文章介绍ES6(ES5+)中新增的比较好用的新特性。本篇聊聊async await。
首先,在阅读本篇文章之前你需要非常了解Promise,如果不了解,可以先移步我的另外一篇锋利的ES6 — Promise。
概念
async函数其实是Generator
的语法糖,详情可以参考锋利的ES6 — Generator。async
函数就是将 Generator 函数的星号(*
)替换成async
,将yield
替换成await
,仅此而已。async
函数可以看作多个异步操作,包装成的一个 Promise 对象,而await
命令就是内部then
命令的语法糖。
优点
内置执行器
Generator
的执行是分两步的,必须要先执行函数本身得到一个遍历器对象再通过yield
来执行,而async
函数自带执行器。也就是说,async
函数的执行,与普通函数一模一样,只需要直接调用即可。更好的语义化
async
和await
,比起星号和yield
,语义更清楚了。async
表示函数里有异步操作,await
表示紧跟在后面的表达式需要等待结果。更广的适用性
async
函数的await
命令后面,可以是 Promise 对象和原始类型的值(数值、字符串和布尔值,但这时会自动转成立即 resolved 的 Promise 对象)。返回值是 Promise
async
函数的返回值是 Promise 对象,这比 Generator 函数的返回值是 Iterator 对象方便多了。你可以用then
方法指定下一步的操作。
用法
先来看看一个简单的Promise
的例子:
1 | const pro = new Promise((resolve, reject) => { |
这种写法虽然不用写回调了,但是仍然需要在then
和catch
里面传入函数来处理,倒不是说Promise
不好,只是async
的写法更加舒服,简直跟同步写法没有区别。改造如下:
1 | function foo () { |
async
修饰的函数内部才能使用await
关键字await
表达式后面的函数需要返回一个Promise
对象await
表达式的结果就是resolve
传递过来的参数
但是,当你运行上面的代码的时候你会发现如果Promise
走了reject
,代码会报错,因为await
只接收resolve
的值不接收reject
,因此我们可以把代码放进try...catch
语句中,改造如下:
1 | async function bar () { |
处理Ajax
1 | function get (url, query, isJson = true) { |
也可以在一个async
函数里使用多个await
1 | async function getTodos () { |
多个await
会等到第一个await
异步完成以后才会执行第二个await
。任意一个异步失败都会进入catch
。
但是,这种写法的话两个异步代码会存在前后顺序关系,第一个异步resolve
之后第二个才会开始发送,为了节约时间我们可以换一种写法:
1 | async function getTodos () { |
或者:
1 | async function getTodos () { |
这两种写法都是并行执行多个异步,这样就会缩短程序的执行时间。
代码不是万能的,但不写代码是万万不能的
Dary记
-
更多干货,尽在公众号
转载请注明来源,文末有原始链接。欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 dary1112@foxmail.com
创作不易,您的打赏是我更新的动力
-
支付宝
-
微信
文章标题:锋利的ES6 — Async Await
文章字数:1.1k
本文作者:Dary
发布时间:2020-05-28, 18:51:00
最后更新:2020-05-28, 19:07:47
原始链接:http://www.xiongdalin.com/2020/05/28/ES6-async-await/版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。
Built By Dary