async/await,了解一下?
Promise 的方式雖然解決了 callback hell,但是這種方式充滿了 Promise的 then() 方法,如果處理流程複雜的話,整段代碼將充滿 then,代碼流程不能很好的表示執行流程。
為什麼是async/await
在 es6 中,我們可以使用 Generator 函數控制流程,如下面這段代碼:
我們可以根據不斷地調用 Generator 對象的 方法來控制函數的流程。但是這樣彷彿不是那麼的語義化。因此,在 ES6 中封裝了 Generator 函數的語法糖 async 函數,但是將其定義在了 es7 中。ES7 定義出的 函數,終於讓 JavaScript 對於非同步操作有了終極解決方案。 函數是 Generator 函數的語法糖。使用 關鍵字 來表示,在函數內部使用 await 來表示非同步。相較於 Generator,Async 函數的改進在於下面幾點:Generator 函數的執行必須依靠執行器,而 函數自帶執行器,調用方式跟普通函數的調用一樣。 和 await 相較於 和 更加語義化。 函數返回值是 Promise 對象,比 Generator 函數返回的 Iterator 對象方便,可以直接使用 方法進行調用。
那麼,我們通過一段小小的代碼來說明 async/await 函數的用法:
未使用 async/await 的定時函數:
我相信能看到這裡的各位程序員大佬應該都知道這段代碼的輸出狀況:先列印 2,2s 之後列印出 1。
使用 async/await 的定時函數:
這一段函數的輸出狀況是:2s 後列印 1,然後列印 2。
那麼,why?
我們在字面上理解這兩個單詞 async 和 await:async 的意思是非同步,async 用於定義一個非同步函數,該函數返回一個 Promise。;await 的意思是等待,Promise 是一個承諾,await 也是一個承諾。Promise 的承諾是將返回值輸出到 then 的回掉函數裡面,無論是成功還是失敗。await 的承諾是無論颳風還是下雨,我都會等你完成在做其他的步驟。因此,在上面的運用了 async/await 的代碼中,會等待 fn 完全運行完成並且非同步的回調完成對返回值的處理之後在開始進行下一步操作的。其原理是將非同步函數轉變為同步操作。
實際運用
在上周的工作中,我在一段基於 node 完成的爬蟲操作中多次運用 async/await 來控制程序的執行流程:
其實操作就這麼點,大家看一下代碼都會懂。但是問題是,當我不使用 async/await 時,會產生的情況是會先訪問 2000 + 個數據,不斷訪問其 16 個介面,但是由於 promise 的 then 的回調函數為非同步的,會掛起,而不是直接將數據存到資料庫中。這貌似和我們預想的不一樣啊。因此,我在這裡使用了 async/await 函數,使用同步處理非同步操作,將 promise 同步化,當 axios.all 訪問完成這每一條數據的 16 個介面後,直接將數據存儲到資料庫中,然後才會走到循環的下一層,依舊是訪問下一條數據的 16 個介面。
async/await 的身後事
我們說過了 函數返回值是 Promise 對象。
那麼其內部一旦拋出異常,則會導致返回的 Promise 對象狀態變為 狀態。拋出的錯誤而會被 方法回調函數接收到。
並且,async 有一個和 promise.all 相似的特性,就是內部一點有一個 await 函數報錯,後續的就不再執行了
當 Promise 出現的時候,我們彷彿看到了回調地獄的滅亡。當 Async/Await 出現時,非同步終於不是一件困難的事情。
原文:http://www.cnblogs.com/lunlunshiwo/p/8922500.html 作者:阿爾卑斯de秘密
TAG:JavaScript |