使用ES2017的Async功能
前言
觀察那些已經做了很多季、很多期的綜藝節目,要保持新鮮觀眾又愛看的真是一件需要花很多時間、精力去做的事情。
今日早讀文章由@池盛星翻譯分享。
正文從這開始~
ES2017於6月份定稿, 並帶來了廣受支持的我最喜歡的JavaScript功能: async功能! 如果你曾經被JavaScript的非同步推理搞得焦頭爛額, 那麼這就是為您準備的. 如果沒有, 那麼恭喜, 你肯定是一個超級天才.
非同步功能或多或少允許你編寫順序的JavaScript代碼, 而不需要封裝你的所有的邏輯到callbacks, generators或者promises. 看下面的代碼:
這段代碼並不能按照您所期待的方式執行. 如果您曾經有過JS的編程經驗, 您應該知道是為什麼.
但是下面這段代碼卻能按照您的意圖來執行:
這段代碼看起來非常的直觀, 優雅. 關鍵是能按照我們的意圖執行, 並且與前面一段代碼相比, 僅僅增加了兩個單詞而已!
ES6之前的非同步JavaScript
在我們深入async和await之前, 理解promises是很重要的前提. 而要搞明白promises, 我們要回到普通的callbacks.
Promises是在ES6中被引入的, 並且極大的改進了在JavaScript中的非同步編程. 再也不需要去管大家平時所熟知的」回調地獄」.
callback是一個回調函數, 它可以被傳遞給一個函數並在該函數內部被調用, 作為對函數內部的任何事件的響應. 這是JavaScript 的基礎 .
這個函數只是讀取一個遠程文件獲取數據並在控制台列印輸出, 在文件被完全下載到本地之前, 這是不可能的完成的. 它看起來很簡單, 但是如果你想按順序讀取和列印5個不同的文件該怎麼辦?
在Promises被引入之前, 為了按順序執行任務, 你不得不嵌套回調函數callbacks, 如下:
這看起來讓人頭暈轉向, 彷彿掉進了地獄. 這還不包括對於因為某個文件不存在而完全可能導致的請求錯誤的處理 .
Promise
Promise是一種對尚未返回的數據的一種承諾, 但是你知道它一定會返回的. Kyle Simpson, 你不知道的JS系列的作者, 因非同步JavaScript演講而聞名. 在他的演講中, 他對promises的解釋是: 就像從快餐店訂購食物一樣.
下訂單
付款並且得到一張帶訂單號的小票
等待您的食物
當食物已經準備好, 他們會叫您的小票號碼
收到食物
他指出, 當您在等待您的食物的時候, 您可能不能嘗到它, 但您可以想像它, 並準備享用它. 您可以等待一整天因為您知道食物即將到來, 即使您還沒有得到它, 但是它已經被承諾給您了. 這就是Promise, 代表無論如何最終將存在的數據的對象.
這就是promise的語法. 它的主要好處是允許直觀的鏈式調用連續事件. 這個簡單的例子已經很好, 但是您會發現我們仍然在使用回調函數. Promises只是對callbacks的簡單的封裝, 使它更加直觀.
最(新)好的方式: Async / Await
幾年前, async功能已經進入了JavaScript生態系統. 但直到上個月(2017年6月), 才被JavaScript官方收錄, 並獲得廣泛支持.
async和await是基於promises和generators的一個輕巧的封裝. 本質上, 它允許在任何我們想要的地方使用await關鍵字來」暫停」我們的函數(功能).
這段代碼能夠按照我們的正常理解來按順序執行. 它列印調用API返回的數據. 如果您還沒有感到興奮, 我也不知道該怎麼辦了.
這樣做的好處是直觀. 您可以跟著您的思路一直往下寫代碼, 告訴腳本在需要的地方暫停等待即可.
另一個極大的好處是, 您可以使用在promises中不能使用的try和catch 功能:
這是一個為了說明問題而人為構造的例子, 但它證明了一點: catch將捕獲程序執行的過程中try裡面任何步驟可能發生的錯誤. try代碼塊裡面至少有三個可能執行失敗的地方, 這是迄今為止, 在非同步代碼中捕獲錯誤的最簡潔清晰的方法.
我們還可以輕鬆的在循環和條件語句中使用async:
這個例子有點傻, 但是它可以按照您所期待的執行, 並且很容易讀懂. 如果您在控制台執行這段代碼, 您將發現, for循環裡面每執行一次循環就會調用一次sleep, 暫停一秒進入下一個循環.
細節與要點
現在, 您已經被async和await的美所折服, 那麼就讓我們來更深入了解一下他們的細節:
async和await基於promises. 如果一個函數使用async, 那麼它總是返回一個promise. 意識到這一點非常重要, 並且這很可能是一個將來您會掉進去的大坑.
當我們await時, 它只暫停了這個函數, 而不是阻塞整個進程.
async和await是非阻塞的.
您仍然可以使用像Promise.all()這樣的Promise助手. 以下是我們稍早的例子結合使用promise:
await只能用於被標記為async的函數(方法).
因此, 您不能在全局作用域中使用await.
已經可以使用啦
截至2017年6月, 幾乎所有的瀏覽器都支持async和await關鍵字. 更贊的是, 為了確保您的代碼在任何地方都能工作, 可以使用Babel將JavaScript進行預處理, 以支持舊版本瀏覽器及舊的語法.
如果您對ES2017更多內容感興趣, 請查看完整的ES2017 新特性
【第1026期】ES8 新特性一覽.
瀏覽器支持情況
關於本文
譯者:@池盛星
作者:@ ERIC WINDMIL
原文:http://2ality.com/2016/02/ecmascript-2017.html
點擊展開全文
※【第1032期】前端國際化
※咦?瀏覽器都能做人臉檢測了?
※你應該知道的Debug技巧
※ES8 新特性一覽
※【第1025期】理解Service Worker
TAG:前端早讀課 |
※iOS 12 Beta 5的所有新功能
※Windows Server 2016-Win Ser 2016新增功能
※蘋果在iOS 11.3 beta 3中刪除AirPlay 2功能
※macOS 10.13.6 推出 iTunes 加入 AirPlay 2 功能
※三星為Galaxy A8-2018和J7 Prime發布新功能
※WWDC2018:watchOS 5加入「對講機」功能
※Windows 10 Build 17639更新:強化Sets功能
※蘋果發布iOS 11.3 beta 3 刪除AirPlay 2功能
※Win10 RS5預覽版17618推送:Sets功能回歸,支持Win32應用
※Istio 發布 1.0 正式版本、Windows Server 2019 增加 K8S 功能
※92項新功能!鎚子舊機型專用Smartisan OS v4.1.0發布
※蘋果發布 iOS 11.4 beta1,AirPlay2功能回歸
※Windows 10 Build 17120發布:WDAG功能可下載文檔至主機
※iOS 11.3 beta3有15個新功能!
※使用Unity 2018.1項目模板功能
※iOS 12 VS Android P:5個讓iOS 12脫穎而出的功能
※經典播放器VLC Windows10 UWP版更新v3.0.0:功能實用
※【品牌】6.15 iPhoneSE2發布?iOS12新功能抄安卓
※蘋果iOS 11.3還有新功能:開放Face ID
※科技早報 – iPhoneX比其他機型受捧、Facebook推出約會新功能 – 20180502