jQuery中$.when()方法和deferred对象相关总结

目录

概述

jQuery.when( deferreds )
1.提供一种方法来执行零个或多个对象的回调函数, Deferred(延迟)对象通常表示异步事件。

2.如果没有参数传递给 jQuery.when(),它会返回一个resolved状态的Promise。

3.如果传递一个非Deferred或Promise对象给jQuery.when(),那么它会被当作是一个被解决(resolved)的延迟对象,并且绑定到上面的任何doneCallbacks 都会被立刻执行。向 doneCallbacks 中传入的是原始的参数。在这种情况下,设定的任何 failCallbacks 永远都不会被执行,因为延迟对象永远不会被拒绝(rejected)。

4.如果向 jQuery.when() 传入一个单独的延迟对象,那么会返回它的 Promise 对象(延迟方法的一个子集)。可以继续绑定 Promise 对象的其它方法,例如, defered.then 。

1
2
3
$.when( $.ajax("test.aspx") ).then(function(data, textStatus, jqXHR) {
alert( jqXHR.status ); // alerts 200
});

5.在多个延迟对象传递给jQuery.when() 的情况下,该方法根据一个新的“宿主”Deferred(延迟)对象,跟踪所有已通过Deferreds聚集状态,返回一个Promise对象。当所有的延迟对象被解决(resolve)时,“宿主”Deferred(延迟)对象才会解决(resolved)该方法,或者当其中有一个延迟对象被拒绝(rejected)时,“宿主”Deferred(延迟)对象就会reject(拒绝)该方法。如果“宿主”Deferred(延迟)对象是(resolved)解决状态时, “宿主” Deferred(延迟)对象的 doneCallbacks(解决回调)将被执行。参数传递给doneCallbacks提供这解决(resolved)值给每个对应的Deferreds对象,并匹配Deferreds传递给 jQuery.when()的顺序。 例如:

1
2
3
4
5
6
7
8
9
10
var d1 = $.Deferred();
var d2 = $.Deferred();

$.when( d1, d2 ).done(function ( v1, v2 ) {
console.log( v1 ); // "Fish"
console.log( v2 ); // "Pizza"
});

d1.resolve( "Fish" );
d2.resolve( "Pizza" );

6.在多延迟情况下,如果Deferreds延迟对象一被拒绝(rejected),jQuery.when()触发立即调用“宿主”Deferred(延迟)对象的failCallbacks。请注意在这个时间点上,有一些延迟对象仍然可以是未解决(unresolved)的。


实例

  实际项目中曾有这样的场景:同一个页面有多个模块的业务,需要查询不同的数据源。页面加载完成或者点击查询后,会发出多个异步请求,它们返回的先后是不一定的,而想对查询结果做一个统一处理,比如超时重试,错误处理等,就应该使用$.when

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
//时间查询点击“确定”按钮
$("#submitButton").click(function(){
$(".portrait_make,.portrait_make1,.portrait_make2").addClass("hide");
var searchTime = $("#recordTime").val();
if(searchTime==null||searchTime==''){
alert("请选择查询日期!");
}else{
opType=1;
var formatRecordTime=getSearchTimeFormat2(searchTime);
$("#hideSearchTime").val(formatRecordTime);

searchBtnStatusHandler("toSearch");

// ... ... 省略若干业务逻辑

//initTimeEChart等四个方法返回的都是$.ajax({})的deferred对象
var deferred = [];
deferred.push(initTimeEChart(formatRecordTime));
deferred.push(initAllFunnelEchartAndTable(formatRecordTime));
deferred.push(initKeyModel(formatRecordTime));
deferred.push(initKeyGroupModel(formatRecordTime));
deferred.push(refreshPieEchartAll(formatRecordTime));

errorStack = [];

$.when.apply($,deferred)
.done(function () {
searchBtnStatusHandler("toReset");
})
.fail(function () {
alert(errorStack.join(";"));
searchBtnStatusHandler("toReset");
})
}
});

//时间搜索按钮状态处理函数
function searchBtnStatusHandler(operation){
if(operation == "toSearch"){
$("#submitButton").html("查询中...");
$("#submitButton").css("background-color","#EDEFF3");
$("#submitButton").css("pointer-events","none");
} else {
$("#submitButton").html("确定");
$("#submitButton").css("background-color","transparent");
$("#submitButton").css("pointer-events","auto");
}
}