Deferred 實現異步編程

JavaScript 的執行流程分爲"同步"與"異步"。傳統的異步操作會在操作完成之後,使用回調函數傳回結果,而回調函數中則包含了後續的工作。我們一直習慣於“線性”地編寫代碼邏輯,但是大量異步操作所帶來的回調函數,會把我們的算法分解地支離破碎。


以動畫爲例,下一個動畫要等上一個執行完畢纔可以繼續,流程就會寫到回調函數裏面
// 執行多個動畫
$('ele1').animate({opacity:'0.5'},4000,function(){
    $('ele2').animate({width:'100px'},2000,function(){
        $('ele3').animate({height:'0'},2000);
    });
});

上面的代碼編程邏輯也是正確的,但是針對這樣的異步嵌套的回調邏輯,當我們的嵌套越多,代碼結構層級會變得越來越深。首先

是閱讀上會變得困難,其次是強耦合,接口變得不好擴展。


jQuery 引入了 Deferred 的概念。 Deferred 是一種令代碼異步行爲更加優雅的抽象,有了它,我們就可以像寫同步代碼一樣去寫

異步代碼。這個東西看起來很複雜,實際上我們只要抓住核心的使用就可以了。Deferred對象就是jQuery的回調函數解決方案。在

英語中,defer的意思是"延遲",所以deferred對象的含義就是"延遲"到未來某個點再執行。


通過 $.Deferred 處理過的代碼,很明顯沒有了回調的嵌套,雖然代碼量看起來多了點,但是實際上,每一個代碼執行部分都被封裝

了起來,只留了Deferred的接口處理,等於是我們把執行的流程控制交給了Deferred,這樣的好處就是我們在寫嵌套函數的時候,

可以用deferred提供的管道風格編寫同步代碼了。


代碼示例:

function animate1() {
    var dtd = $.Deferred(); // 創建Deferred對象
    $("#block1").animate({width:400px},2000,function() {
        dtd.resolve(); // 改變Deferred對象的執行狀態爲“已完成”
    });
    return dtd;
}
function animate2() {
    var dtd = $.Deferred(); // 創建Deferred對象
    $("#block2").animate({width:"50%"}, 2000, function() {
        dtd.resolve(); // 改變Deferred對象的執行狀態爲“已完成”
    });
    return dtd;
}
var anim = animate1();
anim.then(function() {
    $("#block1").text('block1動畫結束');
    return animate2();
}).then(function() {
    $("#block2").text('block2動畫結束');
});


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章