摘要:假如返回的不是一個對象,是其他的任何返回值,后面的語句會立即執行。而關鍵字只有得到返回值后才繼續執行,不就是同步么。
最近在學習NodeJS框架koa V2,koa2的API很簡單,基于ES7 async/await實現異步代碼。很多人認為async/await是解決異步終極解決方案,那我們就研究下async/await。
前端業務邏輯越來越復雜,往往幾個 AJAX 請求之間互有依賴,有些請求依賴前面請求的數據,有些請求需要并行進行。我們用ajax來做個例子,根據查找一個省份中的第一個市的區縣。
$.get("/url/city",[province:"河北省"],function (result1){ console.log(result1); $.get("/url/county",[city:result1[1]],function (result2){ console.log(result2); }) })
這個是用回調函數執行的異步操作,大量的異步操作就有大量的回調函數,現在我們是嵌套來三層,假如我們嵌套了四層五層更多層,這個時候使用回調函數來寫代碼往往會導致代碼難以閱讀,就會形成了回調地獄Callback hell。
現在我們用比較優雅一點的,看起來像同步實則異步的async/await 重構一下代碼。
var requestUrl=(url,args)=>{ return new Promise(function(resolve,reject){ $.get(url,args,(result)=> { try { resolve(JSON.parse(result)); }catch(e){ reject(e); } }) }) } async function getCounty(province){ try{ let result1=await requestUrl("/url/city",{provinces:province}); console.log(result1); }catch(e){ console.log(e); } try{ let result2=await requestUrl("/url/county",{city:result1[1]}); console.log(result2); }catch(e){ console.log(e); } }; getCounty("河北省");
首先我們定義了一個requestUrl函數,這個函數返回一個Promise對象resolve,并拿到結果,立即執行函數定義時使用了關鍵字async,在函數體中配合使用了await,執行第一個await會返回‘/url/province’的執行數據所有河北省的市,執行第二個await,返回根據第一個市里面的區縣。
現在我們了解一下async/await的用法;
async關鍵字表示這個是一個異步函數,await只能使用在這個函數里面,如果是在普通函數就會報錯;
await的作用是獲取一個promise對象,獲取返回值之前await后面的語句是無法繼續執行的。假如await返回的不是一個promise對象,是其他的任何返回值,await后面的語句會立即執行。
ajax比較容易看出call hell問題,現在我們弄個簡單的例子,可以在babel中執行一下。
var sleep = function (time) { setTimeout(function () { console.log("test"); }, time); }; var start = async function () { console.log("start"); await sleep(3000); console.log("end"); };
start();
這個是沒有返回promise對象的例子,執行start()后,先輸出’start‘,然后"end",三秒鐘后輸出"test";
var sleep = function (time) { return new Promise(function (resolve, reject) { setTimeout(function () { resolve("test"); console.log("test"); }, time); }) }; async function start() { console.log("start"); let result = await sleep(8000); console.log("end"); }; start(); 這個是返回promise對象,它先輸出‘start’,然后是等待三秒輸出‘test’,最后輸出‘end’;
在學習過程中,我被一句話給誤導了,‘看起來像同步實則異步的async/await’,就走到了一個死胡同里,await關鍵字聲明一個異步函數,但是await阻止了await后面語句執行,只有await等到了一個返回值才會繼續執行,這不就是同步執行了嗎?徹底的懵了,后來恍然大悟,async聲明start()為異步函數,假如再有一個start2(),它們并行執行的,在babel里面測試如下圖:
所以異步的點在這。而await關鍵字只有得到返回值后才繼續執行,不就是同步么。搞定!!!
async函數返回一個Promise對象,可以使用then()添加回調,catch()捕獲異常,當我們也可以用try/catch,就是
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/81730.html
摘要:異步編程三座大山原型原型鏈作用域閉包同步異步。異步操作執行完畢后,再執行該回調函數,確保回調在異步操作之后執行。回調函數本身是我們約定俗成的一種叫法,我們定義它,但是并不會自己去執行它,它最終被其他人執行了。 JS異步編程 JS三座大山:原型原型鏈、作用域閉包、同步異步。之前有寫過自己對閉包的理解,今天來總結一下JS中的異步。 思考(案例來自stackoverflow): functi...
摘要:函數會在之后的某個時刻觸發事件定時器。事件循環中的這樣一次遍歷被稱為一個。執行完畢并出棧。當定時器過期,宿主環境會把回調函數添加至事件循環隊列中,然后,在未來的某個取出并執行該事件。 原文請查閱這里,略有改動。 本系列持續更新中,Github 地址請查閱這里。 這是 JavaScript 工作原理的第四章。 現在,我們將會通過回顧單線程環境下編程的弊端及如何克服這些困難以創建令人驚嘆...
摘要:下面開始分析開頭的代碼第一輪事件循環流程整體作為第一個宏任務進入主線程,遇到,輸出遇到函數聲明,聲明暫時不用管遇到,其回調函數被分發到微任務中。我們記為遇到,其回調函數被分發到宏任務中。 先上一道常見的筆試題 console.log(1); async function async1() { console.log(2); await async2(); con...
摘要:的翻譯文檔由的維護很多人說,阮老師已經有一本關于的書了入門,覺得看看這本書就足夠了。前端的異步解決方案之和異步編程模式在前端開發過程中,顯得越來越重要。為了讓編程更美好,我們就需要引入來降低異步編程的復雜性。 JavaScript Promise 迷你書(中文版) 超詳細介紹promise的gitbook,看完再不會promise...... 本書的目的是以目前還在制定中的ECMASc...
閱讀 649·2021-11-11 16:55
閱讀 2160·2021-11-11 16:55
閱讀 1951·2021-11-11 16:55
閱讀 2341·2021-10-25 09:46
閱讀 1598·2021-09-22 15:20
閱讀 2270·2021-09-10 10:51
閱讀 1703·2021-08-25 09:38
閱讀 2612·2019-08-30 12:48