我需要等到我的所有ajax功能都完成,然后继续执行exectution。
我的具体情况是我需要在提交之前翻译表单中的某些字段。我通过对外部站点的ajax调用来翻译它们。根据表单中的某些值,我需要做更多或更少的翻译。完成所有翻译后(如果有的话)我必须用ajax验证表格,如果有效,则提交。
这是我的理由:
首先,我有一个函数发送ajax调用并对收到的数据做一些事情:
function translate(...) {
$("#ajaxCounter").val(parseInt($("#ajaxCounter").val()) + 1);
$.ajax({
...
success:function(data) {
...
$("#ajacCounter").val(parseInt($("#ajaxCounter").val()) - 1);
}
});
然后,当要提交表单时,我执行以下代码:
$("#form").submit(function() {
translatable_fields.each(function() {
translate(...);
});
while (parseInt($("#ajaxCounter").val()) > 0) { null; }
if (!(this).hasClass('ready')) {
$.ajax({
//validation
success: function(data) {
if (data['isValid']) {
$("#form").addClass('ready');
$("#form").submit();
}
}
});
}
return true;
});
问题是提交函数中的while
循环永远不会结束。
如果我执行没有while
循环的代码,我可以看到ajaxCounter
输入在翻译函数开始时增加,在结束时减少。
答案 0 :(得分:13)
您可以使用deferred
调用返回的$.ajax
对象以更整洁的方式实现此目的。首先,您应该获得translate()
函数以返回deferred
:
function translate(...){
return $.ajax({
// settings...
});
});
然后你可以将所有这些承诺放在一个数组中:
var requests = [];
translatable_fields.each(function(){
requests.push(translate(...));
});
然后您可以apply
将该数组$.when
:
$.when.apply($, requests).done(function(schemas) {
console.log("All requests complete");
// do something...
});
答案 1 :(得分:1)
您可以使用延迟对象执行此操作,但如果您只对最终完成感兴趣,则不需要将$.when.apply
与数组一起使用。
相反,您可以使用模式promise = $.when(promise, another promise)
更改您的翻译以返回Ajax承诺:
function translate(...) {
...
return $.ajax({
...
});
}
并且您的承诺循环变为:
var promise; // Start with an undefined promise - which is the same as a resolved promise for $.when
translatable_fields.each(function() {
promise = $.when(promise, translate(...));
});
// Wait for all promises to complete
promise.done(function(){
// now do the final code after all the ajax calls complete
});
注意:
$.when
调用创建了一个额外的承诺,但开销非常小,结果代码非常简单。答案 2 :(得分:0)
不,你不能像这样循环:回调永远不会被调用。
我会做这样的事情:
function translateAllFields(done) {
var requestsInProgress = 0, doneCalled = false;
translatable_fields.each(function () {
++requestsInProgress;
$.ajax({
//...
success: function (data) {
//...
$("#ajacCounter").val(parseInt($("#ajaxCounter").val()) - 1);
}
}).always(function () {
if (--requestsInProgress === 0) {
done();
doneCalled = true;
}
});
});
if (requestsInProgress === 0 && !doneCalled) {
// in case translatable_fields was empty
done();
}
}
然后:
$("#form").submit(function (e) {
if (!(this).hasClass('ready')) {
e.preventDefault();
e.stopPropagation();
translateAllFields(function() {
$.ajax({
//validation
success: function (data) {
if (data['isValid']) {
$("#form").addClass('ready');
$("#form").submit();
}
}
});
});
}
});
答案 3 :(得分:-2)
您可以使用回调
function translate(..., callback) {
$.ajax({
...
success:function(data) {
...
callback(data);
}
});
};
将你的ajax代码传递给它
$("#form").submit(function() {
translatable_fields.each(function() {
translate(..., function(result){
if (!(this).hasClass('ready')) {
$.ajax({
//validation
success: function(data) {
if (data['isValid']) {
$("#form").addClass('ready');
$("#form").submit();
}
}
});
}
return true;
});
});
});