1. 首页
  2. IT资讯

如何简单理解 JavaScript 的 Async 和 Await?

“u003Cdivu003Eu003Cdiv class=”pgc-img”u003Eu003Cimg src=”http:u002Fu002Fp9.pstatp.comu002Flargeu002Fpgc-imageu002F4f49cab5a1ac4f019bfead3b4701f16d” img_width=”1920″ img_height=”1080″ alt=”如何简单理解 JavaScript 的 Async 和 Await?” inline=”0″u003Eu003Cp class=”pgc-img-caption”u003Eu003Cu002Fpu003Eu003Cu002Fdivu003Eu003Cpu003E自从Async 和Await 出现后,大幅简化JavaScript 同步和非同步(异步)的复杂纠葛,这篇文章将会分享我自己理解的历程,实站await 等待、连续输入文字、fetch 和回调应用,让这些过去需要层层callback才能完成的流程,透过 Async 和 Await 轻松的进行扁平化处理吧!u003Cu002Fpu003Eu003Ch1u003E什么是async?什么是await?u003Cu002Fh1u003Eu003Cpu003E在JavaScript的世界,同步sync和非同步async的爱恨情仇,就如同偶像剧一般的剪不断理还乱,特别像是setTimeout、setInterval、MLHttpRequest或fetch这些同步非同步混杂的用法,都会让人一个头两个大,幸好ES6出现了promise,ES7出现了async、await,帮助我们可以更容易的进行业务逻辑的编写。u003Cu002Fpu003Eu003Cpu003E对于同步和非同步,最常见的说法是「同步模式下,每个任务必须按照顺序执行,后面的任务必须等待前面的任务执行完成,非同步模式则相反,后面的任务不用等前面的,各自执行各自的任务」,但我觉得这样实在不容易理解,不容易理解的地方在于「中文」的同步和非同步,可能和实际上的解释刚好相反了(同步的中文字面意思是「一起走」,非同步的中文意思是「不要一起走」,超容易搞错的),因此如果你跟我一样也很容易搞错,可以使用我觉得比较好理解的方法:「同一个赛道vs不同赛道」,透过步道的方式,就更容易明白同步和非同步。u003Cu002Fpu003Eu003Cblockquoteu003Eu003Cpu003E同步:在「同一个赛道」比赛「接力赛跑」,当棒子没有交给我,我就得等你,不能跑。u003Cu002Fpu003Eu003Cpu003E非同步:在「不(非)同赛道」比赛「赛跑」,谁都不等谁,只要轮到我跑,我就开始跑。u003Cu002Fpu003Eu003Cu002Fblockquoteu003Eu003Cdiv class=”pgc-img”u003Eu003Cimg src=”http:u002Fu002Fp1.pstatp.comu002Flargeu002Fpgc-imageu002F1ae669a41e024e6f95112d937ce0990d” img_width=”418″ img_height=”310″ alt=”如何简单理解 JavaScript 的 Async 和 Await?” inline=”0″u003Eu003Cp class=”pgc-img-caption”u003Eu003Cu002Fpu003Eu003Cu002Fdivu003Eu003Cpu003E在ES7里头 async 的本质是 promise 的语法糖(包装得甜甜的比较好吃下肚),只要 function标记为 async,就表示里头可以编写 await 的同步语法,而 await 顾名思义就是「等待」,它会确保一个 promise 物件都解决( resolve )或出错( reject )后才会进行下一步,当 async function 的内容全都结束后,会返回一个 promise ,这表示后方可以使用 .then 语法来做连接,基本的程式长相就像下面这样:u003Cu002Fpu003Eu003Cdiv class=”pgc-img”u003Eu003Cimg src=”http:u002Fu002Fp1.pstatp.comu002Flargeu002Fpgc-imageu002F539d4ec881e845458c33089c5c6ec028″ img_width=”1772″ img_height=”1732″ alt=”如何简单理解 JavaScript 的 Async 和 Await?” inline=”0″u003Eu003Cp class=”pgc-img-caption”u003Eu003Cu002Fpu003Eu003Cu002Fdivu003Eu003Ch1u003E利用async 和 await 做个「漂亮的等待」u003Cu002Fh1u003Eu003Cpu003E了解 async 和 await 的意思之后,就来试试看做个「漂亮的等待」:u003Cu002Fpu003Eu003Cdiv class=”pgc-img”u003Eu003Cimg src=”http:u002Fu002Fp1.pstatp.comu002Flargeu002Fpgc-imageu002F6aa4ee13defa4fb59c54ea7643a7504e” img_width=”2096″ img_height=”2308″ alt=”如何简单理解 JavaScript 的 Async 和 Await?” inline=”0″u003Eu003Cp class=”pgc-img-caption”u003Eu003Cu002Fpu003Eu003Cu002Fdivu003Eu003Cpu003E如果我们把上面的范例修改为 async 和 await 的写法,突然就发现代码看起来非常的干净,因为 await 会等待收到 resolve 之后才会进行后面的动作,如果没有收到就会一直处在等待的状态,所以什么时候该等待,什么时候该做下一步,就会非常清楚明了,这也就是我所谓「漂亮的等待」。u003Cu002Fpu003Eu003Cpu003E注意,await 一定得运行在async function 内!u003Cu002Fpu003Eu003Cdiv class=”pgc-img”u003Eu003Cimg src=”http:u002Fu002Fp1.pstatp.comu002Flargeu002Fpgc-imageu002Fd90017012766455c8d010efe778b140a” img_width=”3244″ img_height=”1652″ alt=”如何简单理解 JavaScript 的 Async 和 Await?” inline=”0″u003Eu003Cp class=”pgc-img-caption”u003Eu003Cu002Fpu003Eu003Cu002Fdivu003Eu003Ch1u003E搭配Promiseu003Cu002Fh1u003Eu003Cpu003E基本上只要有 async 和 await 的地方,就一定有 promise 的存在,promise 顾名思义就是「保证执行之后才会做什么事情」,刚刚使用了 async 、await 和 promise 改善 setTimeout这个容易出错的非同步等待,针对 setInterval ,也能用同样的做法修改,举例来说,下面的代码码执行之后,并「不会」如我们预期的「先显示1,再显示 haha0…haha5 ,最后再显示2」,而是「先显示1和2,然后再出现 haha0…haha5」,因为虽然程式逻辑是从上往下,但在count function里头是非同步的语法,导致自己走自己的路,也造成了结果的不如预期。u003Cu002Fpu003Eu003Cdiv class=”pgc-img”u003Eu003Cimg src=”http:u002Fu002Fp1.pstatp.comu002Flargeu002Fpgc-imageu002F87c4889605bb4f388ffca035268f1a6c” img_width=”2048″ img_height=”1860″ alt=”如何简单理解 JavaScript 的 Async 和 Await?” inline=”0″u003Eu003Cp class=”pgc-img-caption”u003Eu003Cu002Fpu003Eu003Cu002Fdivu003Eu003Cpu003E时我们可以透过 async、await 和 promise 进行修正,在显示1之后,会「等待」count function结束后再显示2。u003Cu002Fpu003Eu003Cdiv class=”pgc-img”u003Eu003Cimg src=”http:u002Fu002Fp9.pstatp.comu002Flargeu002Fpgc-imageu002F62d2f2971aba4c56ac7de44684f8479d” img_width=”2308″ img_height=”2380″ alt=”如何简单理解 JavaScript 的 Async 和 Await?” inline=”0″u003Eu003Cp class=”pgc-img-caption”u003Eu003Cu002Fpu003Eu003Cu002Fdivu003Eu003Cpu003EsetTimeout 和 setInterval ,这也可以应用于「输入文字」的场景,过去我们要做到「连续输入」文字,可能要层层叠叠写个好几个callback,现在如果使用async和await,就能够很简单的实现连续输入的情境,程式码看起来也更干净简洁。u003Cu002Fpu003Eu003Cpu003Eu003Cstrongu003Ehtml结构:u003Cu002Fstrongu003Eu003Cu002Fpu003Eu003Cdiv class=”pgc-img”u003Eu003Cimg src=”http:u002Fu002Fp1.pstatp.comu002Flargeu002Fpgc-imageu002F00080b8641754771a9a5f67a32151b70″ img_width=”1828″ img_height=”820″ alt=”如何简单理解 JavaScript 的 Async 和 Await?” inline=”0″u003Eu003Cp class=”pgc-img-caption”u003Eu003Cu002Fpu003Eu003Cu002Fdivu003Eu003Cpu003Eu003Cstrongu003Ejs代码:u003Cu002Fstrongu003Eu003Cu002Fpu003Eu003Cdiv class=”pgc-img”u003Eu003Cimg src=”http:u002Fu002Fp1.pstatp.comu002Flargeu002Fpgc-imageu002F48028aec7bc7469b9818b35479af8e57″ img_width=”3392″ img_height=”2692″ alt=”如何简单理解 JavaScript 的 Async 和 Await?” inline=”0″u003Eu003Cp class=”pgc-img-caption”u003Eu003Cu002Fpu003Eu003Cu002Fdivu003Eu003Cblockquoteu003Eu003Cpu003EinsertAdjacentHTML() 将指定的文本解析为HTML或XML,并将结果节点插入到DOM树中的指定位置。它不会重新解析它正在使用的元素,因此它不会破坏元素内的现有元素。这避免了额外的序列化步骤,使其比直接innerHTML操作更快。u003Cu002Fpu003Eu003Cu002Fblockquoteu003Eu003Ch1u003E搭配Fetchu003Cu002Fh1u003Eu003Cpu003E在上篇的文章 JavaScript Fetch API 使用教学已经有提到 fetch 的用法,因为 fetch 最后回传的是promise,理所当然的通过async和await操作是最恰当不过的。u003Cu002Fpu003Eu003Cpu003E举例来说,先前往类似阿里云的获取天气 API 的平台可以取得许多气象资料,搜索某个城市的现在天气报告,通过 fetch的json() 方法处理返回数据,结果显示出「北京市的即时气温」。u003Cu002Fpu003Eu003Cpu003E透过 async 和 await 的简化代码,得到的结果完全不需要 callback 的辅助,就能按照我们所期望的顺序进行。( 先显示「开始调用API」,接着显示「北京市的气温」,最后显示「气温结果」 )u003Cu002Fpu003Eu003Cdiv class=”pgc-img”u003Eu003Cimg src=”http:u002Fu002Fp3.pstatp.comu002Flargeu002Fpgc-imageu002F75e5a8c5dbe94360aed08924fd9c84d5″ img_width=”4096″ img_height=”1860″ alt=”如何简单理解 JavaScript 的 Async 和 Await?” inline=”0″u003Eu003Cp class=”pgc-img-caption”u003Eu003Cu002Fpu003Eu003Cu002Fdivu003Eu003Ch1u003E搭配循环u003Cu002Fh1u003Eu003Cpu003E如果要通过 JavaScript 实现「文字慢慢变大」的效果,除了透过CSS的transition设定之外,通常就是直接使用 setInterval 来完成,就像下面的代码这样:u003Cu002Fpu003Eu003Cdiv class=”pgc-img”u003Eu003Cimg src=”http:u002Fu002Fp1.pstatp.comu002Flargeu002Fpgc-imageu002F91a8c14164d04c8285b8798b368c7783″ img_width=”2048″ img_height=”1444″ alt=”如何简单理解 JavaScript 的 Async 和 Await?” inline=”0″u003Eu003Cp class=”pgc-img-caption”u003Eu003Cu002Fpu003Eu003Cu002Fdivu003Eu003Cpu003E搭配async 和await,我们就能将同样的做法,因为使用了await,所以每次执行时,都会进行「等待」,也就能做到字体慢慢变大的效果。u003Cu002Fpu003Eu003Cpu003Eu003Cstrongu003Ehtml结构:u003Cu002Fstrongu003Eu003Cu002Fpu003Eu003Cdiv class=”pgc-img”u003Eu003Cimg src=”http:u002Fu002Fp1.pstatp.comu002Flargeu002Fpgc-imageu002F2d9e418801ce476cae3a33f6e709bf59″ img_width=”1528″ img_height=”612″ alt=”如何简单理解 JavaScript 的 Async 和 Await?” inline=”0″u003Eu003Cp class=”pgc-img-caption”u003Eu003Cu002Fpu003Eu003Cu002Fdivu003Eu003Cpu003Eu003Cstrongu003Ejs代码:u003Cu002Fstrongu003Eu003Cu002Fpu003Eu003Cdiv class=”pgc-img”u003Eu003Cimg src=”http:u002Fu002Fp1.pstatp.comu002Flargeu002Fpgc-imageu002F8bac0cec5a4a440c97516e9f92546274″ img_width=”3084″ img_height=”1860″ alt=”如何简单理解 JavaScript 的 Async 和 Await?” inline=”0″u003Eu003Cp class=”pgc-img-caption”u003Eu003Cu002Fpu003Eu003Cu002Fdivu003Eu003Cpu003Eu003Cstrongu003E运行效果:u003Cu002Fstrongu003Eu003Cu002Fpu003Eu003Cdiv class=”pgc-img”u003Eu003Cimg src=”http:u002Fu002Fp3.pstatp.comu002Flargeu002Fpgc-imageu002Fad3fd04e58ce4439b485f611dbd58556″ img_width=”299″ img_height=”158″ alt=”如何简单理解 JavaScript 的 Async 和 Await?” inline=”0″u003Eu003Cp class=”pgc-img-caption”u003Eu003Cu002Fpu003Eu003Cu002Fdivu003Eu003Cpu003E同样的,上面提到的fetch 或是输入文字,只要做成await 的方式,都可以放在循环里面使用,例如通过循环不断的 fetch 资料、通过循环不断的输入文字…等,这些就不是callback 方法能容易办到的啰~u003Cu002Fpu003Eu003Cdiv class=”pgc-img”u003Eu003Cimg src=”http:u002Fu002Fp1.pstatp.comu002Flargeu002Fdfic-imagehandleru002F1046b67f-418f-4477-806e-a1a052a0f219″ img_width=”1023″ img_height=”683″ alt=”如何简单理解 JavaScript 的 Async 和 Await?” inline=”0″u003Eu003Cp class=”pgc-img-caption”u003Eu003Cu002Fpu003Eu003Cu002Fdivu003Eu003Cblockquoteu003Eu003Cpu003E文章参考来源:https:u002Fu002Fwww.oxxostudio.twu002Farticlesu002F201908u002Fjs-async-await.htmlu003Cu002Fpu003Eu003Cpu003E原文作者:oxxostudiou003Cu002Fpu003Eu003Cpu003E由于网页为繁体内容,术语描述和话术与我们有差异的问题,笔者在保证不改变原意的基础上做了调整,并在此基础上进行了错误校正,如发现问题,欢迎你的指正u003Cu002Fpu003Eu003Cu002Fblockquoteu003Eu003Ch1u003E小结u003Cu002Fh1u003Eu003Cpu003E坦白说只要你一但熟悉了async 和await,就真的回不去了,虽然说callback 仍然是程式开发里必备的功能,但对于同步和非同步之间的转换,以后就交给async 和await来处理吧!u003Cu002Fpu003Eu003Cpu003E简单了解之后,如果你想深入学习的话,笔者建议你看看我以前写的两篇文章:u003Ca class=”pgc-link” data-content=”mp” href=”https:u002Fu002Fwww.toutiao.comu002Fi6711875170585281031u002F?group_id=6711875170585281031″ target=”_blank”u003E「JavaScript基础」Promise使用指南u003Cu002Fau003E、u003Ca class=”pgc-link” data-content=”mp” href=”https:u002Fu002Fwww.toutiao.comu002Fi6712224316961849863u002F?group_id=6712224316961849863″ target=”_blank”u003E「JavaScript基础」深入学习asyncu002Fawaitu003Cu002Fau003E,相信你看完后会有不小的收获。u003Cu002Fpu003Eu003Cpu003E更多精彩内容,请u003Cstrongu003E关注“前端达人”公众号u003Cu002Fstrongu003Eu003Cu002Fpu003Eu003Cu002Fdivu003E”

原文始发于:如何简单理解 JavaScript 的 Async 和 Await?

主题测试文章,只做测试使用。发布者:杀手梦三刀,转转请注明出处:http://www.cxybcw.com/10714.html

联系我们

13687733322

在线咨询:点击这里给我发消息

邮件:1877088071@qq.com

工作时间:周一至周五,9:30-18:30,节假日休息

QR code