<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
        主站蜘蛛池模板: 特级aaaaaaaaa毛片免费视频| 日韩精品亚洲人成在线观看| 亚洲成年网站在线观看| 亚州免费一级毛片| 亚洲成AV人片久久| 在线观看av永久免费| 国内精品久久久久影院亚洲| 91免费资源网站入口| 亚洲日本VA午夜在线电影| 免费看a级黄色片| 日韩毛片免费一二三| 77777亚洲午夜久久多人| 免费av片在线观看网站| 久久久亚洲欧洲日产国码二区 | 日本一道一区二区免费看 | 成年女人喷潮毛片免费播放| 中文字幕无码亚洲欧洲日韩| 成人黄软件网18免费下载成人黄18免费视频 | 污污视频免费观看网站| 美腿丝袜亚洲综合| 蜜桃视频在线观看免费视频网站WWW| 亚洲精品电影天堂网| 日韩免费观看的一级毛片| 瑟瑟网站免费网站入口| 亚洲av无码一区二区乱子伦as| 最近中文字幕2019高清免费| 亚洲无码一区二区三区 | 黄页网站在线观看免费高清| 亚洲av第一网站久章草| 亚洲综合色自拍一区| 亚洲一区二区三区免费观看| 国产精品久久久久久亚洲影视| 国产av无码专区亚洲av果冻传媒 | 一级毛片全部免费播放| 亚洲熟妇成人精品一区| 亚洲乱码国产一区三区| 免费国产黄线在线观看| 香蕉免费看一区二区三区| 亚洲国产成人精品久久 | 性xxxx视频播放免费| 免费国产污网站在线观看|