You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
async function run(){
var articles = await getArticleList();
var article = await getArticle(articles[0].id);
var author = await getAuthor(article.authorId);
alert(author.email);
}
好消息是,我們上面有關ES6的code都是通過babel這個library轉換成ES5的語法
而他有個實驗性功能的地方,其中就有包含async
而async是在stage 2,NOTE: Stage 2 and above are enabled by default.
什麼參數都不用調整就自動幫你開啟了,真是可喜可賀
在Javascript裡面,有一個超級重要的概念就是非同步,這也是剛入門的時候最容易搞混、忘記的觀念
ES6原生支援了
Promise
,搭配Generator
使用效果更佳,而ES7甚至支援了async
的語法我覺得這算是一個演進的過程,讓程式架構越來越好、可讀性越來越高
所以要講解這些新的東西,就先從最基本的callback開始吧
現在假設我們有三個api
第一個是抓取文章列表的api
第二個是給文章id, 抓取文章內容的api
第三個是給作者id, 返回作者資訊的api
現在想要達成的功能是:抓取最新的一篇文章的作者信箱
流程就是:抓文章列表->抓文章資訊->抓作者
實作成code就像這樣
或可參考線上範例:用callback實做
相信這樣子的code大家應該都不陌生,但是這樣會有一個缺點
就是我們俗稱的callback hell,這樣一層一層一層的實在是有點醜
那該怎麼辦呢?有種東西叫做
Promise
,就這樣出現了先來個實際範例再來講解吧!
線上範例:用Promise實做
Promise
是一個物件,有三種狀態,等待中(pending)、完成(resolve or fulfilled)跟失敗(reject)在上面的範例中,我們把那三個函數的callback function拿掉了,取而代之的是返回一個Promise物件
原本應該是
callback
要出現的地方,變成了resolve
這樣有什麼好處呢?看我們最上面呼叫這些函式的地方,原本的callback hell不見了,被我們壓平了
如果看的不是很懂,就先從最基本的,呼叫一個Promise開始
你可以在Promise物件後面加上
.then
,就會是這個Promise跑完之後的結果假如在
then
裡面return另一個Promise
物件,就可以不斷串接使用像是這樣
有了Promise的這個特性,就可以避免掉callback hell
如果我們加上ES6的arrow function,甚至可以簡化成這樣
線上範例 Promise+arrow function
單純運用Promise的範例就到這邊為止,其實到這邊語法已經滿簡單的了,而且有了arrow function以後,可讀性有變得比較好,但是看到一堆
then
總是覺得有點礙眼那接下來還有什麼呢?
ES6裡面多了一個Generator,如果不知道的話可參考我的上一篇文章[Javascript] ES6 Generator基礎
接著就要利用Generator的特性,來寫出超級像同步但其實是非同步的程式碼
完整版線上範例 Promise + Generator
仔細看
run
這個generator,利用yield
的特性,會先執行右邊的程式碼,等待下一次的呼叫並且賦值給左邊所以我們可以在
getArticleList()
裡面的then
事件呼叫gen.next(r1)
,就會把回傳值丟給articles
這個變數如果覺得這樣有點難懂,可以先換成只有一層的
讓我們再回來看看上面那段程式碼的上半部
有沒有覺得,跟同步的程式碼很像?只要把
yield
拿掉的話,根本就一模一樣對吧!這就是generator的精髓所在了:用很像同步的語法,但其實是非同步
那再來看看下半部
很容易可以發現下半部的語法很固定,並且容易找出規律
而且根本就是個遞迴
所以可以用一個函式包住,處理更多general的case
完整版線上範例 Promise + Generator + 遞迴
tj做的co模組就是在做差不多的事情,只是做得更多了
但原理跟我們上面寫的
runGenerator
很類似,就是把一個generator包起來寫一個自動執行器最後,終於要講到標題上的最後一個東西了:async
這是什麼?先來看code
完整版線上範例 async(沒辦法跑)
(jsfiddle支援度沒那麼高,所以沒辦法跑這段code)
這段code跟之前的差別在於
function* gen()
變成async function run()
yield
變成await
就這兩個點而已
然後你會發現,就這樣就結束了
不必用其他模組,不必自己寫遞迴執行器
這就是
async
的語法,其實就是把那些自動執行寫好而已,但是這樣的語法讓我們方便許多而其實這個語法是在
ES7
才有計畫引入的,QQ好消息是,我們上面有關ES6的code都是通過babel這個library轉換成ES5的語法
而他有個實驗性功能的地方,其中就有包含
async
而
async
是在stage 2
,NOTE: Stage 2 and above are enabled by default.什麼參數都不用調整就自動幫你開啟了,真是可喜可賀
當初剛接觸ES6時,一下子接觸到一堆眼花撩亂的東西,每個再繼續深入下去都是一門學問
而且我在之前都是純粹用callback(因為層級不多所以還好),偶爾用一下
async
(node的library,跟上面的不一樣)所以我覺得最好了解的方式,就是從最基礎的callback開始,慢慢進步到promise,再進步到generator,最後才是async
才能懂得為什麼會有這些東西的出現
如果有哪些地方有講錯,還麻煩留個言或是寄信給我
感謝
ref:
ECMAScript 6 入门 异步操作
JavaScript Promises
拥抱Generator,告别异步回调
深入浅出ES6(三):生成器 Generators
The text was updated successfully, but these errors were encountered: