重構:從Promise到Async/Await
摘要: 誇張點說,技術的發展與歷史一樣,順之者昌,逆之者亡。JS開發者們,趕緊擁抱Async/Await吧!
- GitHub倉庫: Fundebug/promise-asyncawait
早在半年多之前,我就在鼓吹Async/Await替代Promise的6個理由,似乎還招致了一些批評。然而,直到最近,我才真正開始進行代碼重構,拋棄Promise,全面使用Async/Await。因為,Node 8終於LTS了!
Async/Await真的比Promise好嗎?
是的是的。
這些天,我大概重構了1000行代碼,最大的感覺是代碼簡潔了很多:
- 真正地用同步的方式寫異步代碼
- 不用寫then及其回調函數,減少代碼行數,也避免了代碼嵌套
- 所有異步調用可以寫在同一個代碼塊中,無需定義多余的中間變量
- async函數會隱式地返回一個Promise,因此可以直接return變量,無需使用Promise.resolve進行轉換
下面,我們可以通過一個非常簡單的示例來體驗一下Async/Await的酸爽:
示例1
const Promise = require("bluebird")
|
由示例可知,使用Async/Await極大地簡化了代碼,使得代碼可讀性提高了非常多。
Async/Await真的替代了Promise?
是的是的。
對於Async/Await替代Promise的6個理由,批評者執著於Async/Await是基於Promise實現的,因此替代這個詞不準確,這就有點尷尬了。
一方面,這裏替代的是異步代碼的編寫方式,並非完全拋棄大家心愛的Promise,地球人都知道Async/Await是基於Promise的,不用太傷心;另一方面,Promise是基於回調函數實現的,那Promise也沒有替代回調函數咯?
重構代碼之後,我仍然用到了Promise庫bluebird。”Talk is cheap, Show me the code!”,大家不妨看看兩個示例。
示例2:Promise.promisify
使用Promise.promisify將不支持Promise的方法Promise化,調用異步接口的時候有兩種方式:
const Promise = require("bluebird")
|
Fundebug是全棧JavaScript錯誤監控平臺,支持各種前端和後端框架,可以幫助您第一時間發現BUG!
示例3:Promise.map
使用Promise.map讀取多個文件的數據,調用異步接口的時候有兩種方式:
const Promise = require("bluebird")
|
沒錯,我的確使用了Promise庫,readFile與Promise.map都是Promise函數。但是,在調用readFile與Promise.map函數時,使用Async/Await與使用Promise是兩種不同寫法,它們是相互替代的關系。
Async/Await有什麽問題嗎?
有啊有啊。
使用了await的函數定義時要加一個async,調用異步函數的時候需要加一個await,這玩意寫多了也覺著煩,有時候還容易忘掉。不寫async代碼直接報錯,不寫await代碼執行會出錯。
示例4
const Promise = require("bluebird")
|
既然Async/Await寫著有點添亂,可不可以不寫呢?我想以後應該是可以的,只要能夠自動識別異步代碼就行了,這應該也是未來的發展方向。至於說如何實現,那我就不知道了哎。
總結
JavaScript的異步編寫方式,從回調函數到Promise再到Async/Await,表面上只是寫法的變化,本質上則是語言層的一次次抽象,讓我們可以用更簡單的方式實現同樣的功能,而程序員不需要去考慮代碼是如何執行的。在我看來,這樣的進步應該不會停止,有一天我們也許不用寫Async/Await了!
參考
- Async/Await替代Promise的6個理由
- Async/Await是這樣簡化JavaScript代碼的
版權聲明: 轉載時請註明作者Fundebug以及本文地址: https://blog.fundebug.com/2017/12/13/reconstruct-from-promise-to-async-await/
重構:從Promise到Async/Await