摘要:一方面,這里替代的是異步代碼的編寫方式,并非完全拋棄大家心愛的,地球人都知道是基于的,不用太傷心另一方面,是基于回調(diào)函數(shù)實現(xiàn)的,那也沒有替代回調(diào)函數(shù)咯重構(gòu)代碼之后,我仍然用到了庫。
摘要: 夸張點說,技術(shù)的發(fā)展與歷史一樣,順之者昌,逆之者亡。JS開發(fā)者們,趕緊擁抱Async/Await吧!
GitHub倉庫: Fundebug/promise-asyncawait
早在半年多之前,我就在鼓吹A(chǔ)sync/Await替代Promise的6個理由,似乎還招致了一些批評。然而,直到最近,我才真正開始進行代碼重構(gòu),拋棄Promise,全面使用Async/Await。因為,Node 8終于LTS了!
Async/Await真的比Promise好嗎?是的是的。
這些天,我大概重構(gòu)了1000行代碼,最大的感覺是代碼簡潔了很多:
真正地用同步的方式寫異步代碼
不用寫then及其回調(diào)函數(shù),減少代碼行數(shù),也避免了代碼嵌套
所有異步調(diào)用可以寫在同一個代碼塊中,無需定義多余的中間變量
async函數(shù)會隱式地返回一個Promise,因此可以直接return變量,無需使用Promise.resolve進行轉(zhuǎn)換
下面,我們可以通過一個非常簡單的示例來體驗一下Async/Await的酸爽:
示例1const Promise = require("bluebird") var readFile = Promise.promisify(require("fs").readFile) // 使用Promise function usePromise() { let a readFile("a.txt", "utf8") .then(tmp => { a = tmp return readFile("b.txt", "utf8") }) .then(b => { let result = a + b console.log(result) // 輸出"Hello, Fundebug!" }) } // 使用Async/Await async function useAsyncAwait() { let a = await readFile("a.txt", "utf8") let b = await readFile("b.txt", "utf8") let result = a + b console.log(result) // 輸出"Hello, Fundebug!" } usePromise() useAsyncAwait()
由示例可知,使用Async/Await極大地簡化了代碼,使得代碼可讀性提高了非常多。
Async/Await真的替代了Promise?是的是的。
對于Async/Await替代Promise的6個理由,批評者執(zhí)著于Async/Await是基于Promise實現(xiàn)的,因此替代這個詞不準(zhǔn)確,這就有點尷尬了。
一方面,這里替代的是異步代碼的編寫方式,并非完全拋棄大家心愛的Promise,地球人都知道Async/Await是基于Promise的,不用太傷心;另一方面,Promise是基于回調(diào)函數(shù)實現(xiàn)的,那Promise也沒有替代回調(diào)函數(shù)咯?
重構(gòu)代碼之后,我仍然用到了Promise庫bluebird。"Talk is cheap, Show me the code!",大家不妨看看兩個示例。
示例2:Promise.promisify使用Promise.promisify將不支持Promise的方法Promise化,調(diào)用異步接口的時候有兩種方式:
const Promise = require("bluebird") var readFile = Promise.promisify(require("fs").readFile) // 使用Promise function usePromise() { readFile("b.txt", "utf8") .then(b => { console.log(b) }) } // 使用Async/Await async function useAsyncAwait() { var b = await readFile("b.txt", "utf8") console.log(b) // 輸出"Fundebug!" } usePromise() useAsyncAwait()
Fundebug是全棧JavaScript錯誤監(jiān)控平臺,支持各種前端和后端框架,可以幫助您第一時間發(fā)現(xiàn)BUG!
示例3:Promise.map使用Promise.map讀取多個文件的數(shù)據(jù),調(diào)用異步接口的時候有兩種方式:
const Promise = require("bluebird") var readFile = Promise.promisify(require("fs").readFile) var files = ["a.txt", "b.txt"] // 使用Promise function usePromise() { Promise.map(files, file => { return readFile(file, "utf8") }) .then(results => { console.log(results) }) } // 使用Async/Await async function useAsyncAwait() { var results = await Promise.map(files, file => { return readFile(file, "utf8") }) console.log(results) } usePromise() useAsyncAwait()
沒錯,我的確使用了Promise庫,readFile與Promise.map都是Promise函數(shù)。但是,在調(diào)用readFile與Promise.map函數(shù)時,使用Async/Await與使用Promise是兩種不同寫法,它們是相互替代的關(guān)系。
Async/Await有什么問題嗎?有啊有啊。
使用了await的函數(shù)定義時要加一個async,調(diào)用異步函數(shù)的時候需要加一個await,這玩意寫多了也覺著煩,有時候還容易忘掉。不寫async代碼直接報錯,不寫await代碼執(zhí)行會出錯。
示例4const Promise = require("bluebird") var readFile = Promise.promisify(require("fs").readFile) // 沒有Async function withoutAsync() { let b = await readFile("b.txt", "utf8") // 報錯"SyntaxError: Unexpected identifier" console.log(b) } // 沒有await async function withoutAwait() { let b = readFile("b.txt", "utf8") console.log(b) // 打印"Promise..." } withoutAsync() withoutAwait()
既然Async/Await寫著有點添亂,可不可以不寫呢?我想以后應(yīng)該是可以的,只要能夠自動識別異步代碼就行了,這應(yīng)該也是未來的發(fā)展方向。至于說如何實現(xiàn),那我就不知道了哎。
總結(jié)JavaScript的異步編寫方式,從回調(diào)函數(shù)到Promise再到Async/Await,表面上只是寫法的變化,本質(zhì)上則是語言層的一次次抽象,讓我們可以用更簡單的方式實現(xiàn)同樣的功能,而程序員不需要去考慮代碼是如何執(zhí)行的。在我看來,這樣的進步應(yīng)該不會停止,有一天我們也許不用寫Async/Await了!
參考Async/Await替代Promise的6個理由
Async/Await是這樣簡化JavaScript代碼的
版權(quán)聲明:
轉(zhuǎn)載時請注明作者Fundebug以及本文地址:
https://blog.fundebug.com/2017/12/13/reconstruct-from-promise-to-async-await/
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/92443.html
摘要:普通的回調(diào)函數(shù)調(diào)用執(zhí)行后續(xù)邏輯使用了以后的復(fù)雜邏輯獲取到正確的結(jié)果輸出兩個文件拼接后的內(nèi)容雖說解決了的問題,不會出現(xiàn)一個函數(shù)前邊有二三十個空格的縮進。所以直接使用關(guān)鍵字替換原有的普通回調(diào)函數(shù)即可。 從今年過完年回來,三月份開始,就一直在做重構(gòu)相關(guān)的事情。 就在今天剛剛上線了最新一次的重構(gòu)代碼,希望高峰期安好,接近半年的Node.js代碼重構(gòu)。 包含從callback+async.w...
摘要:如果不希望定義多余的外層變量,則需要在鏈中的每一個函數(shù)中都返回變量,這樣做顯然更加糟糕。 譯者按: 通過真實的代碼示例感受Async/Await的力量。 原文: Async/await - A thorough example 譯者: Fundebug 為了保證可讀性,本文采用意譯而非直譯。另外,本文版權(quán)歸原作者所有,翻譯僅用于學(xué)習(xí)。 既然Node.js 8已經(jīng)LTS了,我想大...
摘要:重構(gòu)基于的網(wǎng)絡(luò)請求庫從屬于筆者的開發(fā)基礎(chǔ)與工程實踐系列文章與項目,記述了筆者對內(nèi)部使用的封裝庫的設(shè)計重構(gòu)與實現(xiàn)過程?;臼褂冒姹局械闹校詈诵牡脑O(shè)計變化在于將請求構(gòu)建與請求執(zhí)行剝離了開來。而函數(shù)則負(fù)責(zé)執(zhí)行請求,并且返回經(jīng)過擴展的對象。 Fluent Fetcher: 重構(gòu)基于 Fetch 的 JavaScript 網(wǎng)絡(luò)請求庫從屬于筆者的 Web 開發(fā)基礎(chǔ)與工程實踐系列文章與項目,記述了...
摘要:假如返回的不是一個對象,是其他的任何返回值,后面的語句會立即執(zhí)行。而關(guān)鍵字只有得到返回值后才繼續(xù)執(zhí)行,不就是同步么。 最近在學(xué)習(xí)NodeJS框架koa V2,koa2的API很簡單,基于ES7 async/await實現(xiàn)異步代碼。很多人認(rèn)為async/await是解決異步終極解決方案,那我們就研究下async/await。前端業(yè)務(wù)邏輯越來越復(fù)雜,往往幾個 AJAX 請求之間互有依賴,有...
閱讀 2722·2021-11-22 13:54
閱讀 1063·2021-10-14 09:48
閱讀 2292·2021-09-08 09:35
閱讀 1550·2019-08-30 15:53
閱讀 1166·2019-08-30 13:14
閱讀 606·2019-08-30 13:09
閱讀 2521·2019-08-30 10:57
閱讀 3334·2019-08-29 13:18