您的位置:首頁>正文

深入理解 JavaScript 非同步系列(5)——async await

第一部分, ES7 中引入 async-await

前面介紹完了Generator的非同步處理, 可以說是跌跌撞撞, 經過各種基礎介紹和封裝, 好容易出了一個比較簡潔的非同步處理方案, 學習成本非常高————這顯然不是我們想要的!

因此, 還未發佈的 ES7 就乾脆自己參照Generator封裝了一套非同步處理方案————async-await。 說是參照, 其實可以理解為是Generator的語法糖!

本節示例代碼參照這裡

本節內容概述Generatorasync-await使用async-await接下來...

Generator和async-await的對比

先來一段Generator處理非同步的代碼, 前面已經介紹過了, 看不明白的再獲取接著看。

co(function* { const r1 = yield readFilePromise('some1.json') console.log(r1) // 列印第 1 個檔內容 const r2 = yield readFilePromise('some2.json') console.log(r2) // 列印第 2 個檔內容 })

再來一段async-await的執行代碼如下, 兩者做一個比較。

const readFilePromise = Q.denodeify(fs.readFile) // 定義 async 函數 const readFileAsync = async function { const f1 = await readFilePromise('data1.json') const f2 = await readFilePromise('data2.json') console.log('data1.json', f1.toString) console.log('data2.json', f2.toString) return 'done' // 先忽略, 後面會講到 } // 執行 const result = readFileAsync

從上面兩端代碼比較看來, async function代替了function*, await代替了yield, 其他的再沒有什麼區別了。 哦, 還有, 使用async-await時候不用再引用co這種協力廠商庫了, 直接執行即可。

使用async-await的不同和好處

第一, await後面不能再跟thunk函數, 而必須跟一個Promise物件(因此, Promise才是非同步的終極解決方案和未來)。 跟其他類型的資料也OK, 但是會直接同步執行, 而不是非同步。

第二, 執行const result = readFileAsync返回的是個Promise物件, 而且上面代碼中的return 'done'會直接被下面的then函數接收到

result.then(data => { console.log(data) // done })

第三, 從代碼的易讀性來將, async-await更加易讀簡介, 也更加符合代碼的語意。 而且還不用引用協力廠商庫, 也無需學習Generator那一堆東西, 使用成本非常低。

因此, 如果 ES7 正式發佈了之後, 強烈推薦使用async-await。 但是現在尚未正式發佈,

從穩定性考慮, 還是Generator更好一些。

接下來...

node v7版本已經開始原生支持async-await了, 不過 node 的目前穩定版本還是v6, 尚不支持, 怎麼辦?———— 當然是萬能的babel!下一節就介紹。

第二部分, 如何在 nodejs v6.x版本中使用 async-await

本節介紹一下如何使用babel來讓 nodev6版本也能運行async-await

本節內容概述安裝必要的外掛程式創建入口檔並執行

安裝必要的外掛程式

運行npm i babel-core babel-plugin-transform-runtime babel-preset-es2015 babel-preset-stage-3 babel-runtime --save安裝一堆需要的外掛程式。

然後在專案根目錄創建.babelrc檔, 檔內容編寫為

{ "presets": ["stage-3", "es2015"], "plugins": ["transform-runtime"] }

創建入口檔並執行

加入你編寫async-await的代碼檔是test.js, 那麼你需要創建另一個檔, 例如test-entry.js作為入口檔。 入口檔內容編寫為

require("babel-core/register"); require("./test.js");

然後直接運行node test-entry.js就可以了

第三部分, 整體總結

一周左右的業餘時間總結完, 寫完, 也是累得我夠嗆。 不算什麼體力活, 但是天天的坐在書桌旁寫這些東西也是很考驗一個人的定力,

沒點耐性是肯定不行的 ———— 這算是獲獎感言嗎
同類文章
Next Article
喜欢就按个赞吧!!!
点击关闭提示