1. 程式人生 > >前端多層回調問題解決方案之$.Deferred

前端多層回調問題解決方案之$.Deferred

fail -s 使用 defer 解決方法 == 默認 don blog

javascript引擎是單線程的,但是通過異步回調可以實現IO操作並行執行能力,當業務邏輯復雜的時候我們就進入回調地獄。

本文講得ajax是在jquery1.5以前的版本,目的旨在讓我們理解延遲對象的應用場景,jquery1.5之後,ajax默認就是延遲對象,可以進行鏈式操作

舉例:

a(funtion(){
    b(funtion(){
        c(funtion(){
            d(funtion(){
                e(funtion(){
                    f(funtion(){
                        g(funtion(){
                            finish();
                        });
                    });
                });
            });
        });
    });
});      

這還是比較簡單的操作,如果每個回調函數還有N多操作,那麽更加頭疼了。

解決方法:通過jQuery的when().done()實現

1. 函數a,b,c,d,e,f,g都這樣寫

function a(){
    var dtd = $.Deferred();

    //這裏延遲操作,可能是ajax,也可能是setTimeout
    $.post(url,{},function(data){
        ....
        alert("執行完畢!");
      dtd.resolve(); // 改變Deferred對象的執行狀態
    }) ;

    return dtd.promise();
}

2. 使用

$.when(
    a(),
    b(),
    c(),
    d(),
    e(),
    f(),
    g()
).done(finish).fail() ;

PS: 除了$.when().done()組合,還有一種組合$.when().then()。

done是在when中的延遲對象dtd都resolve的時候才回執行done中的操作,then是延遲對象有一個resolve就執行。類似於“與”和“或”。

如上的例子,如果a函數裏面的ajax請求返回的不是我們想要的結果,我們不想讓done執行,應該怎麽做呢?

function a(){
    
var dtd = $.Deferred(); //這裏延遲操作,可能是ajax,也可能是setTimeout $.post(url,{},function(data){ if(data == 1){ dtd.resolve(); // 改變Deferred對象的執行狀態 }else{ dtd.reject(); // 作用和resolve正好相反 }    }); return dtd.promise(); }

如果a函數服務器返回的是1, 那麽done可以執行,如果不是1,那麽不會執行done,而是立即執行fail。

如果這裏是then那麽不會受到影響,只要a,b,c,d,e,f,g有一個resolve。

還有一個函數$when().always(),這個不管when中resolve還是reject,最後都會執行always。

文章轉自: http://www.myjscode.com/page/article10.html

前端多層回調問題解決方案之$.Deferred