让我稍微解释一下我的代码(对不起,如果有些错误,我刚刚从头开始编写这个例子,它与我现在的非常接近)。
HTML:
<form id="form">
<!-- Friend 1 -->
Name 1: <input type="text" name="friendName1" id="friendName1" class="friendName" value=""><br />
Email 1: <input type="text" name="friendEmail1" id="friendEmail1" value=""><br /><br />
<!-- Friend 2 -->
Name 2:<input type="text" name="friendName2" id="friendName2" class="friendName" value=""><br />
Email 2:<input type="text" name="friendEmail2" id="friendEmail2" value=""><br /><br />
<!-- Friend 3 -->
Name 3:<input type="text" name="friendName3" id="friendName3" class="friendName" value=""><br />
Email 3:<input type="text" name="friendEmail3" id="friendEmail3" value=""><br /><br />
<!-- Friend 4 -->
Name 4:<input type="text" name="friendName4" id="friendName4" class="friendName" value=""><br />
Email 4:<input type="text" name="friendEmail4" id="friendEmail4" value=""><br /><br />
<!-- Submit -->
<input name="submit" type="submit" value="Submit">
</form>
JS:
$("#form").submit(function(){
$(".friendName[value!='']").each(function(){
var idEmail = 'friendEmail' + $(this).attr("id").replace('friendName','');
if($("#"+idEmail+"[value!='']").length > 0){
var name = $(this).val();
var email = $("#"+idEmail).val();
// Submit the ajax request
$.ajax({
type: 'POST',
url: 'ajax/url',
data: {
name: name,
email: email
},
success: function(json) {
// Log a console entry if our ajax request was successful
console.log(name + " was submitted via ajax");
}
});
}
});
// Redirect the user to the thank you page
setTimeout( function() { window.location= '/thanks'; }, 2000 );
});
JSFiddle (重定向已删除,ajax调用已替换为控制台日志以供小提琴使用)
HTML是一个简单的表单,包含朋友姓名和朋友电子邮件输入字段。
JS有一个函数,如果名称和相关的电子邮件有值,它会运行一个ajax调用。
我需要一种方法让这些ajax调用运行(可能有1个循环,可能有15个),然后在它们全部完成之后,重定向到新页面。
我正在做的当前方式非常糟糕,因为在页面重定向之前,所有的ajax调用都没有完成运行。
我可以做些什么来改善它?它需要是万无一失的,并且只有在所有ajax调用完成后才会重定向(成功或错误,无关紧要 - 它只需要在完成后重定向)。
我尝试使用async: false
,但似乎没有什么区别。
我考虑过在每个函数中放置一个计数器,在ajax成功函数中设置一个计数器,如果它们都匹配,那么重定向,但我正在寻找一些更有经验的指导。
答案 0 :(得分:28)
$("#form").submit(function(e){
e.preventDefault();
var calls = [];
$(".friendName[value!='']").each(function(){
// Submit the ajax request
calls.push($.ajax({
type: 'POST',
url: 'ajax/url',
data: {
name: name,
email: email
},
success: function(json) {
// Log a console entry if our ajax request was successful
console.log(name + " was submitted via ajax");
}
}));
});
$.when.apply($, calls).then(function() {
window.location= '/thanks';
});
});
答案 1 :(得分:6)
好的,这很简单,因为你正在使用jQuery。 jQuery带有一个集成的promise工具,它也与jQuery的Ajax调用连接在一起。那是什么意思?好吧,我们可以很容易地这样:
var requests = [ ];
// ...
// Submit the ajax request
requests.push($.ajax({
type: 'POST',
url: 'ajax/url',
data: {
name: name,
email: email
},
success: function(json) {
// Log a console entry if our ajax request was successful
console.log(name + " was submitted via ajax");
}
}));
// at this point we filled our array with jXHR objects which also inherit the promise API
$.when.apply( null, requests ).done(function() {
document.location.href = '/thanks';
});
注意:如果所有请求都成功完成,则上述代码将仅触发。如果您需要处理此案例,如果一个或多个请求失败,请使用.then()
或.fail()
代替.done()
。
答案 2 :(得分:2)
只需保留AJAX调用的计数器并检查它们何时完成。 像这样:
$("#form").submit(function(){
var ajaxMax = $(".friendName[value!='']").length, ajaxCounter = 0;
$(".friendName[value!='']").each(function(){
var idEmail = 'friendEmail' + $(this).attr("id").replace('friendName','');
if($("#"+idEmail+"[value!='']").length > 0){
var name = $(this).val();
var email = $("#"+idEmail).val();
// Submit the ajax request
$.ajax({
type: 'POST',
url: 'ajax/url',
data: {
name: name,
email: email
},
success: function(json) {
// Log a console entry if our ajax request was successful
console.log(name + " was submitted via ajax");
if(++ajaxCounter >= ajaxMax)
window.location= '/thanks';
}
});
}
});
});
答案 3 :(得分:0)
默认情况下,$ .ajax是异步的。在传递的选项哈希中,添加
async: false
这会将你正在进行的调用序列化,让它按照你想要的方式运行。
在收到原始海报的评论后,可能的解决办法可能是:
注意,我没有关于执行此类操作的线程安全性的任何信息,所以YMMV。
示例代码:
$("#form").submit(function(eventObject){
var $ajaxFields= $(".friendName[value!='']").filter(function(index){
var idEmail = 'friendEmail' + $(this).attr("id").replace('friendName','');
return ($("#"+idEmail+"[value!='']").length > 0);
});
var numberToSubmit= $ajaxFields.length;
$ajaxFields.each(function(){
var idEmail = 'friendEmail' + $(this).attr("id").replace('friendName','');
var name = $(this).val();
var email = $("#"+idEmail).val();
// Submit the ajax request
$.ajax({
type: 'POST',
url: 'ajax/url',
data: {
name: name,
email: email
},
success: function(json) {
// Log a console entry if our ajax request was successful
console.log(name + " was submitted via ajax");
},
error: function(jqXHR, textStatus, errorThrown) {
console.log("call not completed: "+textStatus);
},
complete: function(jqXHR, textStatus) {
if( --numberToSubmit == 0 ) {
window.location.href= '/thanks';
}
}
});
});
// Prevent default form submission
return false;
});