兼容IE大佬的異步流程控制大法

其實工做中一直都有異步流程控制的需求,主要是各類須要順序執行的AJAX。jquery

以前請求很少的時候,我就直接簡單粗暴地在回調裏調用下一個請求函數,隨着項目愈來愈大,愈來愈複雜,這種方式難以維護的缺點就愈加的明顯。大熱的ES6中的promise方法的確很強,然而,須要兼容IE7(如今是IE10了)的我流下了兩行清淚....並且咱們項目還未引入打包和配置工具(沒錯就是這麼落後),因此沒有辦法愉快地使用Promise等ES6語法和對象。數組

這個問題一直很是困擾我,想了好久都沒有比較好的解決辦法,直到有一天,看到了一個CSS3動畫的製做,依賴JQ,控制異步動畫的時候徹底使用了deferred對象,彷彿打開了異步流程新世界的大門promise

deferred對象的使用方法

  1. 建立Deferred對象
  2. 在異步流程結束後改變deferred對象狀態
  3. 返回deferred對象
function F(){
    var def = $.Deferred();  //建立deferred對象
    setTimeout(function(){
        console.log("hi~");
        def.resolve();    //改變deferred對象狀態爲「已完成」
    },50);
    return def; //返回deferred對象
}
複製代碼

而後在須要的地方調用這個異步函數,使用then表示該方法執行完後再執行下一步bash

F().then(function(){
    //do something you want
});
複製代碼

恩,媽媽不再用擔憂個人異步了,即使是有多個異步回調須要控制,也能使用連續的then寫出漂亮的順序流異步

F1().then(function(){
    F2();
}).then(function(){
    F3();
});
複製代碼

彷佛回調依賴的問題已經解決了,直到有一天,我遇到了一個循環異步回調函數

一個流程依賴多個異步回調

大體需求是,有一個循環體,裏面的循環內容是異步流程,大概能夠寫成這樣工具

for(var i = 0 ;i < 10 ; i++){
        setTimeout(function(){
            console.log("我要吃飯啦~"+i);
        });
    }
 console.log("我吃飽啦~")

複製代碼

promise對象裏有個all,能夠用放入數組的形式控制多個異步依賴,沒有編譯工具又要保證兼容性的我再次留下兩行清淚。。研究了半天,好像沒有在Deferred對象中發現有相似的方法。學習

因而先是嘗試着,仍是使用單個流程控制的方法去寫測試

function wait(){
    var deferred = $.Deferred();
     for(var i = 0 ;i < 10 ; i++){
        setTimeout(function(){
            console.log("我要吃飯啦~"+i); 
            deferred.resolve();
        });
    }
    return deferred;
}

wait().then(function(){
    console.log("我吃飽啦~")
})
複製代碼

emmmmm固然這是不對的了,循環第一次的時候,deferred狀態就已經更改成完成,因此就會執行「我吃飽啦」,而後再繼續執行剩餘的9次。動畫

image.png

因而,我作了以下改寫,使用變量count做爲計數標識,當計數循環完成以後,再改變deferred對象的狀態。

function wait(){
  var dtd = $.Deferred()
   var count = 0;
     for(var i = 0 ;i < 10 ; i++){
        setTimeout(function(){
            console.log("我要吃飯啦~"+i); 
            count++;
            if( count == 10 ){
                 dtd.resolve();
            }
        },500);
    }
    return dtd;
}
wait().done(function(){console.log("我吃飽啦")})
複製代碼

運行10次「我要吃飯啦」,隨後運行「我吃飽啦」

image.png

成功啦~給本身一朵小紅花!

兼容性測試

最後的最後,在IE的各個環境下進行測試,竟然在IE5下也能跑。因此只要是能支持JQ的Deferred對象,通常狀況下這種異步流程操做方式都是可行的。

ps:感受本身是走了歪門邪道,不知道deferred對象中是否是有相似於promise對象中的all能夠直接控制多個異步,若是有的話,還但願各位大大能指點迷津

pss:關於公司仍是使用很是傳統開發方式的問題,只能說上有政策的阻礙,下有業務的侷限。緣由很複雜,一時半會兒也說不清,因此只能找機會跑路啦哈哈哈哈

學習資料: jQuery的deferred對象詳解——阮一峯

相關文章
相關標籤/搜索