我有三个功能,我试图运行,前两个正在做一些异步的东西,需要第三个使用的数据。我希望只有当1和2都完成时才会触发第三个函数。这是一般结构,但最终功能是在1和2结束前开始。
function run() {
var data1 = {};
var data2 = {};
$.when(first(), second()).done(constructData());
function first() {
var d = new $.Deferred();
//do a bunch of stuff async
data1 = {};
d.resolve();
}
function second() {
var d = new $.Deferred();
//do a bunch of stuff async
data2 = {};
d.resolve();
}
function constructData() {
//do stuff with data1 and data2
}
}
答案是不立即调用构造数据
$.when(first(), second()).done(constructData);
答案 0 :(得分:24)
您应该返回promise对象。你在这一行中也有错误:
$.when(first(), second()).done(constructData());
应该是
$.when(first(), second()).done(constructData); // don't call constructData immediately
所有这一切可能是:
function run() {
var data1 = {};
var data2 = {};
$.when(first(), second()).done(constructData);
function first() {
return $.Deferred(function() { // <-- see returning Deferred object
var self = this;
setTimeout(function() { // <-- example of some async operation
data1 = {func: 'first', data: true};
self.resolve(); // <-- call resolve method once async is done
}, 2000);
});
}
function second() {
return $.Deferred(function() {
var self = this;
setTimeout(function() {
data2 = {func: 'second', data: true};
self.resolve();
}, 3000);
});
}
function constructData() {
//do stuff with data1 and data2
console.log(data1, data2);
}
}
答案 1 :(得分:1)
我认为您应该first()
和second()
返回承诺:return d.promise();
。来自docs:
如果将单个参数传递给jQuery.when并且它不是Deferred或Promise,则它将被视为已解决的Deferred,并且所有附加的doneCallbacks将立即执行。
我怀疑这可能是when
来电过快呼叫constructData
的原因。
很难从代码中了解到,但请确保在异步操作完成后调用d.resolve()
。
您可能会发现,明确设置data1
和data2
的更自然的方法是使用调用resolve
时提供的数据。这意味着您的when
电话看起来像这样:
$.when(first(), second()).done(function(result1, result2) {
data1 = result1[0];
data2 = result2[0];
constructData();
});
请注意,提供给done
方法的结果的确切格式取决于延迟对象的性质。如果通过致电$.ajax
返回承诺,则结果应为[data, statusText, jqXhrObject]
形式。