摘要:但是的的出現碉堡的新朋友,我們可以輕松寫出同步風格的代碼同時又擁有異步機制,可以說是目前最簡單,最優雅,最佳的解決方案了。不敢說這一定是終極的解決方案,但確實是目前最優雅的解決方案
一、異步解決方案的進化史
JavaScript的異步操作一直是個麻煩事,所以不斷有人提出它的各種解決方案。可以追溯到最早的回調函數(ajax老朋友),到Promise(不算新的朋友),再到ES6的Generator(強勁的朋友)。
幾年前我們可能用過一個比較著名的Async.js,但是它沒有擺脫回調函數,并且錯誤處理也是按照“回調函數的第一個參數用來傳遞錯誤”這樣一個約定。而眾所周知的回調地獄仍然是一個比較突出的問題,直到Generator改變了這種異步風格。
但是ES7的async await的出現(碉堡的新朋友),我們可以輕松寫出同步風格的代碼同時又擁有異步機制,可以說是目前最簡單,最優雅,最佳的解決方案了。
async await語法比較簡單,可以認為是Generator的語法糖,比起星號和yield更具有語義化。下面一個簡單的例子表示1秒之后輸出hello world:
function timeout(ms) { return new Promise((resolve) => { setTimeout(resolve, ms); }); } async function asyncPrint(value, ms) { await timeout(ms); console.log(value) } asyncPrint("hello world", 1000);
await只能用在async函數中,如果用在普通函數就會報錯
await后面跟的是一個Promise對象(當然其它值也可以,但是會包裝成一個立即resolve的Promise,也就沒有意義了)
await會等待Promise的結果返回再繼續執行
await等待的雖然是Promise對象,但是不必寫.then(),直接可以得到返回值,將上面的代碼微調,發現返回值result也是可以輸出hello world:
function timeout(ms) { return new Promise((resolve) => { setTimeout(_ => {resolve("hello world")}, ms); }); } async function asyncPrint(ms) { let result = await timeout(ms); console.log(result) } asyncPrint(1000);三、async await錯誤處理
前面說了await等待的雖然是Promise對象,但是不必寫.then(),所以其實也不用寫.catch()了,直接用try catch就能捕捉錯誤,這樣可以避免錯誤處理代碼非常冗余和笨重,還是將上面的例子微調:
function timeout(ms) { return new Promise((resolve, reject) => { setTimeout(_ => {reject("error")}, ms);//reject模擬出錯,返回error }); } async function asyncPrint(ms) { try { console.log("start"); await timeout(ms);//這里返回了錯誤 console.log("end");//所以這句代碼不會被執行了 } catch(err) { console.log(err); //這里捕捉到錯誤error } } asyncPrint(1000);
如果有多個await,可以一起放在try catch中:
async function main() { try { const async1 = await firstAsync(); const async2 = await secondAsync(); const async3 = await thirdAsync(); } catch (err) { console.error(err); } }四、async await注意點
1). 前面已經說過,await命令后面的Promise對象,運行結果很可能是reject或邏輯報錯,所以最好把await放在try catch代碼塊中。
2). 多個await命令的異步操作,如果不存在依賴關系,讓它們同時觸發。
const async1 = await firstAsync(); const async2 = await secondAsync();
上面代碼中,async1和async2如果是兩個獨立的異步操作,這樣寫會比較耗時,因為只有firstAsync完成以后,才會執行secondAsync,完全可以用Promise.all優雅地處理:
let [async1, async2] = await Promise.all([firstAsync(), secondAsync()]);
3). await只能用在async函數之中,如果用在普通函數就會報錯:
async function main() { let docs = [{}, {}, {}]; //報錯 await is only valid in async function docs.forEach(function (doc) { await post(doc); console.log("main"); }); } function post(){ return new Promise((resolve) => { setTimeout(resolve, 1000); }); }
在forEach內部方法加上async就可以了:
async function main() { let docs = [{}, {}, {}]; docs.forEach(async function (doc) { await post(doc); console.log("main"); }); } function post(){ return new Promise((resolve) => { setTimeout(resolve, 1000); }); }
但是你會發現3個main是同時輸出的,這就說明post是并發執行的,而不是繼發執行,改成for就可以解決問題,3個main是分別相隔1秒輸出:
async function main() { let docs = [{}, {}, {}]; for (let doc of docs) { await post(doc); console.log("main"); } } function post(){ return new Promise((resolve) => { setTimeout(resolve, 1000); }); }
總之,用了async await之后整個人神清氣爽,可以用非常簡潔和優雅的代碼實現各種花式異步操作,并且在業務邏輯復雜的情況下可以不用陷入回調地獄中。不敢說這一定是終極的解決方案,但確實是目前最優雅的解決方案!
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/90736.html
摘要:順序執行異步函數異步為帶來非阻塞等優勢的同時,同時也在一些場景下帶了不便,如順序執行異步函數,下面總結了一些常用的方法。 火于異步 1995年,當時最流行的瀏覽器——網景中開始運行 JavaScript (最初稱為 LiveScript)。 1996年,微軟發布了 JScript 兼容 JavaScript。隨著網景、微軟競爭而不斷的技術更新,在 2000年前后,JavaScript ...
摘要:從最開始的到封裝后的都在試圖解決異步編程過程中的問題。為了讓編程更美好,我們就需要引入來降低異步編程的復雜性。異步編程入門的全稱是前端經典面試題從輸入到頁面加載發生了什么這是一篇開發的科普類文章,涉及到優化等多個方面。 TypeScript 入門教程 從 JavaScript 程序員的角度總結思考,循序漸進的理解 TypeScript。 網絡基礎知識之 HTTP 協議 詳細介紹 HTT...
摘要:從最開始的到封裝后的都在試圖解決異步編程過程中的問題。為了讓編程更美好,我們就需要引入來降低異步編程的復雜性。寫一個符合規范并可配合使用的寫一個符合規范并可配合使用的理解的工作原理采用回調函數來處理異步編程。 JavaScript怎么使用循環代替(異步)遞歸 問題描述 在開發過程中,遇到一個需求:在系統初始化時通過http獲取一個第三方服務器端的列表,第三方服務器提供了一個接口,可通過...
摘要:文章同步自個人博客上一篇讓自啟動介紹了通過起動器讓跑起來,而本篇采用實現更優雅的異步編程。而采用寫,代碼則是直接運行即可直接運行了,無須寫生成器來運行了,而代碼僅僅是改為改為而已。不過效果確實非常好,讓異步編程更加的同步了。 文章同步自個人博客:http://www.52cik.com/2016/07/11/generator-co.html 上一篇《讓 Generator 自啟動》介...
摘要:的翻譯文檔由的維護很多人說,阮老師已經有一本關于的書了入門,覺得看看這本書就足夠了。前端的異步解決方案之和異步編程模式在前端開發過程中,顯得越來越重要。為了讓編程更美好,我們就需要引入來降低異步編程的復雜性。 JavaScript Promise 迷你書(中文版) 超詳細介紹promise的gitbook,看完再不會promise...... 本書的目的是以目前還在制定中的ECMASc...
閱讀 3818·2023-04-25 19:07
閱讀 3563·2021-11-22 12:02
閱讀 3145·2021-10-12 10:11
閱讀 3922·2021-09-03 10:49
閱讀 2896·2019-08-30 13:21
閱讀 3011·2019-08-30 11:14
閱讀 2093·2019-08-29 15:40
閱讀 2880·2019-08-28 18:29