我是jQuery的新手Deferred并且不明白为什么在成功函数完成之前调用它。我有两个同时的ajax请求,并希望触发一个UI单选按钮单击以迭代从其中一个ajax调用返回的一些数据,这需要20秒才能响应。但是,当在then()内触发单选按钮单击时,要迭代的数据为空。如果我单击另一个单选按钮来过滤数据,然后单击触发的单选按钮,则数据不为空,因为已经有足够的时间来成功加载对象。
对象在第一次(20秒)ajax调用成功加载,并且当这两个调用都被解析时,在then()中触发单击。如果成功完成,为什么然后()会触发点击?
firstAjaxFunc: function(args){
return $.ajax({
type: "POST",
url: REQUEST_URL + "/first-func",
contentType: "application/json",
data: $.toJSON({
propOne: propOne,
propTwo: propTwo
}),
dataType: "json class.models",
context: args.context,
success: args.success,
error: showResponseError
});
},
secondAjaxFunc: function(args){
return $.ajax({
type: "POST",
url: REQUEST_URL + "/second-func",
contentType: "application/json",
data: $.toJSON({
propOne: propOne,
propTwo: propTwo
}),
dataType: "json class.models",
context: args.context,
success: args.success,
error: showResponseError
});
},
$('#load-data').append('<p class="spinner" align="center"><img src="../images/loading_small.gif"/></p>');
this.firstAjaxFunc({
params: {
propOne: propOne,
propTwo: propTwo
},
success: function(data){
this.options.stuff = data;
},
context: this
});
this.secondAjaxFunc({
params: {
propOne: propOne,
propTwo: propTwo
},
success: function(data){
this.options.moreStuff = data;
},
context: this
});
$.when(firstAjaxFunc, secondAjaxFunc).then(this.find(".filter-all").click());
".filter-all click": function(radio, event){
this.showAllData();
},
showAllData: function(){
for(var i = 0; i < this.options.stuff.length; i++){ // this.options.stuff is null
$.merge(stuffArr, this.options.stuff[i].getMyStuff());
}
},
答案 0 :(得分:4)
我看到两个主要问题。
$.when()
接受promises作为参数,而不是回调函数。因此,您需要实际调用传递给它的函数,如下所示:
$.when(this.firstAjaxFunc(...), this.secondAjaxFunc(...)).then(...);
AND,.then()
处理程序必须是回调函数,因此您必须将.then()
处理程序转换为稍后可以调用的回调函数。正如您现在所做的那样,它会立即执行,并将结果传递给.then()
,这解释了为什么.click()
会立即执行。
此外,最好不要将jQuery成功处理程序与promise处理程序混合使用。选择其中一个并始终如一地使用它们。在这种情况下,由于你需要一些promise函数,你应该只使用promises,因为promise规则中的调用顺序和promise处理程序序列是严格描述的,因此调用顺序不会有歧义。
您只是展示了一些代码,因此很难获得完整的上下文,但我认为您需要这样的内容:
var p1 = this.firstAjaxFunc({
params: {
propOne: propOne,
propTwo: propTwo
},
success: function(data){
this.options.stuff = data;
},
context: this
});
var p2 = this.secondAjaxFunc({
params: {
propOne: propOne,
propTwo: propTwo
},
success: function(data){
this.options.moreStuff = data;
},
context: this
});
$.when(p1, p2).then(function() {
this.find(".filter-all").click();
}, showResponseError);
或者,将所有内容转换为承诺:
var self = this;
var p1 = this.firstAjaxFunc({
params: {
propOne: propOne,
propTwo: propTwo
}
});
var p2 = this.secondAjaxFunc({
params: {
propOne: propOne,
propTwo: propTwo
}
});
$.when(p1, p2).then(function(data1, data2) {
// process the results
self.options.stuff = data1[0];
self.options.moreStuff = data2[0];
// carry out action now that both are done
this.find(".filter-all").click();
}, showResponseError);