jquery的deferred使用詳解

目錄(?)[+]

前言

之前在一篇文章中寫過一點when方法的使用,最近看到同事的一篇文章,又詳細學習了deferred方法的各種使用技巧。特此總結。


簡單介紹

deferred對象就是jQuery的回調函數解決方案,jQuery之前的版本在異步回調這一塊做得不是很好,所以後期加上了該解決方案。

images


普遍的ajax操作


我們先來回顧一下jQuery中普通的ajax操作:


$.ajax({
    url: "test.html",
    success: function(){
        alert("哈哈,成功了!");
    },
    error:function(){
        alert("出錯啦!");
    }


});


1.5版本後的新寫法如下:


$.ajax("test.html")
    .done(function(){ alert("哈哈,成功了!"); })


    .fail(function(){ alert("出錯啦!"); });


新版本的寫法相比老版本有一個優勢,就是可以自由添加多個回調函數,他們按照添加順序執行:


$.ajax("test.html")
    .done(function(){ alert("哈哈,成功了!");} )
    .fail(function(){ alert("出錯啦!"); } )
    .done(function(){ alert("第二個回調函數!");} );


爲多個ajax指定回調函數


我們可以通過when方法,爲多個事件指定一個回調函數,這就是我之前在項目中的使用需求:


$.when($.ajax("test1.html"), $.ajax("test2.html"))
.done(function(){ alert("哈哈,成功了!"); })
.fail(function(){ alert("出錯啦!"); });


只有當兩個ajax請求都成功之後,纔會運用done方法。


爲普通操作指定回調函數


前面說到的when是用於ajax方法,而ajax方法其實是deferred對象,如果不是ajax方法,而是普通的函數呢?如果直接像上面一樣使用when,是不會有效果的,會直接執行done方法。


所以我們需要手動新建一個deferred對象:


var dtd = $.Deferred(); // 新建一個deferred對象
var wait = function(dtd){


    var tasks = function(){


        alert("執行完畢!");


        dtd.resolve(); // 改變deferred對象的執行狀態


    };


    setTimeout(tasks,5000);


    return dtd;


};


這裏的resolve就是觸發done的,對應的reject方法則是用來調用fail方法的。




var dtd = $.Deferred(); // 新建一個Deferred對象
var wait = function(dtd){


    var tasks = function(){


        alert("執行完畢!");


        dtd.reject(); // 改變Deferred對象的執行狀態


    };


    setTimeout(tasks,5000);


    return dtd;


};


$.when(wait(dtd))


    .done(function(){ alert("哈哈,成功了!"); })


    .fail(function(){ alert("出錯啦!"); });


進一步優化


上面的代碼有一些問題,就是dtd對象是暴露在全局的,所以我們可以通過在全局進行dtd.resolve()來提前回調。


爲了避免這種情況,jQuery提供了deferred.promise()方法,它的作用是,在原來的deferred對象上返回另一個deferred對象,後者只開放與改變執行狀態無關的方法(比如done方法和fail方法)屏蔽與改變執行狀態有關的方法(比如resolve和reject方法)。


var dtd = $.Deferred(); // 新建一個Deferred對象
var wait = function(dtd){


    var tasks = function(){


        alert("執行完畢!");


        dtd.resolve(); // 改變Deferred對象的執行狀態


    };


    setTimeout(tasks,5000);


    return dtd.promise(); // 返回promise對象


};


var d = wait(dtd); // 新建一個d對象,改爲對這個對象進行操作


$.when(d)


    .done(function(){ alert("哈哈,成功了!"); })


    .fail(function(){ alert("出錯啦!"); });


d.resolve(); // 此時,這個語句是無效的


當然,我們也可以把dtd包在函數內:


var wait = function(dtd){
    var dtd = $.Deferred(); //在函數內部,新建一個Deferred對象
    var tasks = function(){
        alert("執行完畢!");
        dtd.resolve(); // 改變Deferred對象的執行狀態
    };
    setTimeout(tasks,5000);
    return dtd.promise(); // 返回promise對象
};


$.when(wait())
    .done(function(){ alert("哈哈,成功了!"); })
    .fail(function(){ alert("出錯啦!"); });

轉載地址:http://blog.csdn.net/mevicky/article/details/51259543



var dtd = $.Deferred(); // 新建一個Deferred對象
  var wait = function(dtd){
  var map = new BMap.Map("allmap");
  var geolocation = new BMap.Geolocation();
    geolocation.getCurrentPosition(function(r){

if(this.getStatus() == BMAP_STATUS_SUCCESS){
$("#curLongitude").val(r.point.lng);
$("#curLatitude").val(r.point.lat);
$("#curProvince").val(r.address.province);
$("#curCity").val(r.address.city);
console.log('您的位置:'+r.point.lng+','+r.point.lat);
$("#txt1").val('您的位置:'+r.point.lng+','+r.point.lat);
setTimeout(function(){
console.log(1)
dtd.resolve(); // 改變Deferred對象的執行狀態
},5000);

}else {
console.log('failed'+this.getStatus());
}
},{enableHighAccuracy: true});
  return dtd;
  }
$.when(wait(dtd)).done(function(){ console.log("哈哈,成功了!"); })



發佈了40 篇原創文章 · 獲贊 20 · 訪問量 14萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章