<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
        當前位置: 首頁 - 科技 - 知識百科 - 正文

        ES7中利用Await減少回調嵌套的方法詳解

        來源:懂視網 責編:小采 時間:2020-11-27 22:26:34
        文檔

        ES7中利用Await減少回調嵌套的方法詳解

        ES7中利用Await減少回調嵌套的方法詳解:前言 我們知道javascript是沒辦法阻塞的,所有的等待只能通過回調來完成,這就造成了回調嵌套的問題,導致代碼亂到爆,這時候Await就有用處了。 對于await的底層機制這里就不詳述了,以免將文章的篇幅拖的很長,需要的朋友們可以參考這篇文章://www.g
        推薦度:
        導讀ES7中利用Await減少回調嵌套的方法詳解:前言 我們知道javascript是沒辦法阻塞的,所有的等待只能通過回調來完成,這就造成了回調嵌套的問題,導致代碼亂到爆,這時候Await就有用處了。 對于await的底層機制這里就不詳述了,以免將文章的篇幅拖的很長,需要的朋友們可以參考這篇文章://www.g

        前言

        我們知道javascript是沒辦法阻塞的,所有的等待只能通過回調來完成,這就造成了回調嵌套的問題,導致代碼亂到爆,這時候Await就有用處了。

        對于await的底層機制這里就不詳述了,以免將文章的篇幅拖的很長,需要的朋友們可以參考這篇文章://www.gxlcms.com/article/123257.htm,下面開始本文的正式內容。

        利用Await減少回調嵌套

        我們大家在開發的時候,有時候需要發很多請求,然后經常會面臨嵌套回調的問題,即在一個回調里面又嵌了一個回調,導致代碼層層縮進得很厲害。

        如下代碼所示:

        ajax({
         url: "/list",
         type: "GET",
         success: function(data) {
         appendToDOM(data);
         ajax({
         url: "/update",
         type: "POST",
         success: function(data) {
         util.toast("Success!");
         })
         });
         }
        });

        這樣的代碼看起來有點吃力,這種異步回調通常可以用Promise優化一下,可以把上面代碼改成:

        new Promise(resolve => {
         ajax({
         url: "/list",
         type: "GET",
         success: data => resolve(data);
         })
        }).then(data => {
         appendToDOM(data);
         ajax({
         url: "/update",
         type: "POST",
         success: function(data) {
         util.toast("Successfully!");
         }) 
         }); 
        });

        Promise提供了一個resolve,方便通知什么時候異步結束了,不過本質還是一樣的,還是使用回調,只是這個回調放在了then里面。

        當需要獲取多次異步數據的時候,可以使用Promise.all解決:

        let orderPromise = new Promise(resolve => {
         ajax("/order", "GET", data => resolve(data));
        });
        let userPromise = new Promise(resolve => {
         ajax("/user", "GET", data => resolve(data));
        });
        
        Promise.all([orderPromise, userPromise]).then(values => {
         let order = values[0],
         user = values[1];
        });

        但是這里也是使用了回調,有沒有比較優雅的解決方式呢?

        ES7的await/async可以讓異步回調的寫法跟寫同步代碼一樣。第一個嵌套回調的例子可以用await改成下面的代碼:

        // 使用await獲取異步數據
        let leadList = await new Promise(resolve => {
         ajax({
         url: "/list",
         type: "GET",
         success: data => resolve(data);
         });
        });
        
        // await讓代碼很自然地像瀑布流一樣寫下來 
        appendToDom(leadList);
        ajax({
         url: "/update",
         type: "POST",
         success: () => util.toast("Successfully");
        });

        Await讓代碼可以像瀑布流一樣很自然地寫下來。

        第二個例子:獲取多次異步數據,可以改成這樣:

        let order = await new Promise(
         resolve => ajax("/order", data => resovle(data))),
        
         user = await new Promise(
         resolve => ajax("/user", data => resolve(data)));
        
        // do sth. with order/user

        這種寫法就好像從本地獲取數據一樣,就不用套回調函數了。

        Await除了用在發請求之外,還適用于其它異步場景,例如我在創建訂單前先彈一個小框詢問用戶是要創建哪種類型的訂單,然后再彈具體的設置訂單的框,所以按正常思路這里需要傳遞一個按鈕回調的點擊函數,如下圖所示:

        但其實可以使用await解決,如下代碼所示:

        let quoteHandler = require("./quote");
        // 彈出框詢問用戶并得到用戶的選擇
        let createType = await quoteHandler.confirmCreate();

        quote里面返回一個Promise,監聽點擊事件,并傳遞createType:

        let quoteHandler = {
         confirmCreate: function(){
         dialog.showDialog({
         contentTpl: tpl,
         className: "confirm-create-quote"
         });
         let $quoteDialog = $(".confirm-create-quote form")[0];
         return new Promise(resolve => {
         $(form.submit).on("click", function(event){
         resolve(form.createType.value);
         });
         });
         }
        
        }

        這樣外部調用者就可以使用await,而不用傳遞一個點擊事件的回調函數了。

        但是需要注意的是await的一次性執行特點。相對于回調函數來說,await的執行是一次性的,例如監聽點擊事件,然后使用await,那么點擊事件只會執行一次,因為代碼從上往下執行完了,所以當希望點擊之后出錯了還能繼續修改和提交就不能使用await,另外使用await獲取異步數據,如果出錯了,那么成功的resolve就不會執行,后續的代碼也不會執行,所以請求出錯的時候基本邏輯不會有問題。

        要在babel里面使用await,需要:

        (1)安裝一個Node包

        npm install --save-dev babel-plugin-transform-async-to-generator

        (2)在工程的根目錄添加一個.babelrc文件,內容為:

        {
         "plugins": ["transform-async-to-generator"]
        }

        (3)使用的時候先引入一個模塊

        require("babel-polyfill");

        然后就可以愉快地使用ES7的await了。

        使用await的函數前面需要加上async關鍵字,如下代碼:

        async showOrderDialog() {
         // 獲取創建類型
         let createType = await quoteHandler.confirmCreate();
        
         // 獲取老訂單數據 
         let orderInfo = await orderHandler.getOrderData();
        }

        我們再舉一個例子:使用await實現JS版的sleep函數,因為原生是沒有提供線程休眠函數的,如下代碼所示:

        function sleep (time) {
         return new Promise(resolve => 
         setTimeout(() => resolve(), time));
        }
        
        async function start () {
         await sleep(1000);
        }
        
        start();

        babel的await實現是轉成了ES6的generator,如下關鍵代碼:

        while (1) {
         switch (_context.prev = _context.next) {
         case 0:
         _context.next = 2;
         // sleep返回一個Promise對象
         return sleep(1000);
        
         case 2:
         case "end": 
         return _context.stop();
         }
        }

        而babel的generator也是要用ES5實現的,什么是generator呢?如下圖所示:

        生成器用function*定義,每次執行生成器的next函數的時候會返回當前生成器里用yield返回的值,然后生成器的迭代器往后走一步,直到所有yield完了。

        有興趣的可以繼續研究babel是如何把ES7轉成ES5的,據說原生的實現還是直接基于Promise.

        使用await還有一個好處,可以直接try-catch捕獲異步過程拋出的異常,因為我們是不能直接捕獲異步回調里面的異常的,如下代碼:

        let quoteHandler = {
         confirmCreate: function(){
         $(form.submit).on("click", function(event){
         // 這里會拋undefined異常:訪問了undefined的value屬性
         callback(form.notFoundInput.value);
         });
         }
        }
        
        try {
         // 這里無法捕獲到異常
         quoteHandler.confirmCreate();
        } catch (e) {
        
        }

        上面的try-catch是沒有辦法捕獲到異常的,因為try里的代碼已經執行完了,在它執行的過程中并沒有異常,因此無法在這里捕獲,如果使用Promise的話一般是使用Promise鏈的catch:

        let quoteHandler = {
         confirmCreate: function(){
         return new Promise(resolve => {
         $(form.submit).on("click", function(event){
         // 這里會拋undefined異常:訪問了undefined的value屬性
         resolve(form.notFoundInput.value);
         });
         });
         }
        }
        
        quoteHandler.confirmCreate().then(createType => {
        
        }).catch(e => {
         // 這里能捕獲異常
        });

        而使用await,我們可以直接用同步的catch,就好像它真的變成同步執行了:

        try {
         createType = await quoteHandler.confirmCreate("order");
        }catch(e){
         console.log(e);
         return;
        }

        總之使用await讓代碼少寫了很多嵌套,很方便的邏輯處理,縱享絲滑。

        總結

        聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        ES7中利用Await減少回調嵌套的方法詳解

        ES7中利用Await減少回調嵌套的方法詳解:前言 我們知道javascript是沒辦法阻塞的,所有的等待只能通過回調來完成,這就造成了回調嵌套的問題,導致代碼亂到爆,這時候Await就有用處了。 對于await的底層機制這里就不詳述了,以免將文章的篇幅拖的很長,需要的朋友們可以參考這篇文章://www.g
        推薦度:
        標簽: 回調 等待 嵌套
        • 熱門焦點

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 亚洲国产模特在线播放| 亚洲av色影在线| 亚洲高清一区二区三区| 无码人妻一区二区三区免费手机 | 久久青草免费91线频观看站街| 亚洲精品国产福利在线观看| 性xxxx黑人与亚洲| 无码国产精品一区二区免费I6| 亚洲熟妇av一区| 成人无码区免费A片视频WWW| 国产亚洲中文日本不卡二区| 最近2019中文字幕mv免费看| 亚洲一久久久久久久久| 亚洲?V乱码久久精品蜜桃| 一个人看的www在线免费视频 | 国产精品国产自线拍免费软件| 亚洲一区二区三区高清在线观看| 免费黄色毛片视频| 无套内射无矿码免费看黄| h视频在线观看免费完整版| 亚洲国产精品综合久久久| 成年人性生活免费视频| 国产精品亚洲一区二区无码| 爱情岛论坛网亚洲品质自拍| 精品免费tv久久久久久久| 亚洲国产综合精品中文字幕 | 亚洲精品美女网站| 亚洲国产小视频精品久久久三级| 91视频免费观看高清观看完整| 亚洲国产综合91精品麻豆| 免费看美女裸露无档网站| 亚洲AV永久无码精品一福利| 久久久久噜噜噜亚洲熟女综合| 久久午夜无码免费| 亚洲啪AV永久无码精品放毛片| 2048亚洲精品国产| 免费观看美女用震蛋喷水的视频| 色偷偷噜噜噜亚洲男人| 久久久久亚洲AV成人无码网站 | 国产亚洲欧洲精品| 国产精品无码免费播放|