Javascript 添加';回调&x27;在一系列异步XHR调用之后
我偶然发现了一段Ajax代码,它不是100%安全的,因为它混合了异步/同步类型的代码。。。因此,基本上在下面的代码中,我有一个jQuery.each,它获取元素的信息,并为每个元素启动一个Ajax get请求:Javascript 添加';回调&x27;在一系列异步XHR调用之后,javascript,jquery,ajax,asynchronous,Javascript,Jquery,Ajax,Asynchronous,我偶然发现了一段Ajax代码,它不是100%安全的,因为它混合了异步/同步类型的代码。。。因此,基本上在下面的代码中,我有一个jQuery.each,它获取元素的信息,并为每个元素启动一个Ajax get请求: $(search).each(function() { $.ajax({ url: 'save.x3?id='+$(this).attr("id")+'value='$(this).data("value"); success: function(o){ //Update
$(search).each(function() {
$.ajax({
url: 'save.x3?id='+$(this).attr("id")+'value='$(this).data("value");
success: function(o){
//Update UI
},
error: function(o){
//Update UI
}
});
});
//code to do after saving...
显然,“保存后要执行的代码…”通常在所有请求完成之前执行。在理想情况下,我希望服务器端代码一次处理所有请求,并在保存成功回调后移动//代码,但假设这不可能,我将代码更改为类似这样的代码,以确保在继续之前返回所有请求,我仍然不喜欢这些请求:
var recs = [];
$(search).each(function() {
recs[recs.length] = 'save.x3?id='+$(this).attr("id")+'value='$(this).data("value");
});
var counter = 0;
function saveRecords(){
$.ajax({
url: recs[counter],
success: function(o){
//Update progress
if (counter<recs.length){
counter++;
saveRecords();
}else{
doneSavingRecords();
}
},
error: function(o){
//Update progress
doneSavingRecords(o.status);
}
});
}
function doneSavingRecords(text){
//code to do after saving...
}
if (recs.length>0){
saveRecords(); //will recursively callback itself until a failed request or until all records were saved
}else{
doneSavingRecords();
}
var recs=[];
$(搜索)。每个(函数(){
recs[recs.length]=“save.x3?id=”+$(this.attr(“id”)+“value=”$(this.data(“value”);
});
var计数器=0;
函数saveRecords(){
$.ajax({
url:recs[计数器],
成功:功能(o){
//更新进度
如果(计数器0){
saveRecords();//将递归回调自身,直到请求失败或保存所有记录为止
}否则{
doneSavingRecords();
}
因此,我正在寻找一种“最佳”方法,向一系列异步调用添加一点同步功能
谢谢!!如果我理解你的要求,我认为你可以用于此目的。如果我理解你的要求,我认为你可以用于此目的。更好的回答:
function saveRecords(callback, errorCallback){
$('<div></div>').ajaxStop(function(){
$(this).remove(); // Keep future AJAX events from effecting this
callback();
}).ajaxError(function(e, xhr, options, err){
errorCallback(e, xhr, options, err);
});
$(search).each(function() {
$.get('save.x3', { id: $(this).attr("id"), value: $(this).data("value") });
});
}
原始答案:如果它们需要按特定顺序排列,或者页面上有其他常规AJAX事件会影响使用ajaxStop
,这是很好的,但速度会较慢:
function saveRecords(callback){
var recs = $(search).map(function(i, obj) {
return { id: $(obj).attr("id"), value: $(obj).data("value") };
});
var save = function(){
if(!recs.length) return callback();
$.ajax({
url: 'save.x3',
data: recs.shift(), // shift removes/returns the first item in an array
success: function(o){
save();
},
error: function(o){
//Update progress
callback(o.status);
}
});
}
save();
}
然后你可以这样称呼它:
saveRecords(function(){
// Complete will fire after all requests have completed with a success or error
}, function(e, xhr, options, err){
// Error will fire for every error
});
saveRecords(function(error){
// This function will run on error or after all
// commands have run
});
更好的回答:
function saveRecords(callback, errorCallback){
$('<div></div>').ajaxStop(function(){
$(this).remove(); // Keep future AJAX events from effecting this
callback();
}).ajaxError(function(e, xhr, options, err){
errorCallback(e, xhr, options, err);
});
$(search).each(function() {
$.get('save.x3', { id: $(this).attr("id"), value: $(this).data("value") });
});
}
原始答案:如果它们需要按特定顺序排列,或者页面上有其他常规AJAX事件会影响使用ajaxStop
,这是很好的,但速度会较慢:
function saveRecords(callback){
var recs = $(search).map(function(i, obj) {
return { id: $(obj).attr("id"), value: $(obj).data("value") };
});
var save = function(){
if(!recs.length) return callback();
$.ajax({
url: 'save.x3',
data: recs.shift(), // shift removes/returns the first item in an array
success: function(o){
save();
},
error: function(o){
//Update progress
callback(o.status);
}
});
}
save();
}
然后你可以这样称呼它:
saveRecords(function(){
// Complete will fire after all requests have completed with a success or error
}, function(e, xhr, options, err){
// Error will fire for every error
});
saveRecords(function(error){
// This function will run on error or after all
// commands have run
});
>>在理想的情况下,我希望服务器端代码一次处理所有这些代码,并在保存成功回调后移动//代码
你需要从事件的角度来考虑这一点。
Closure的net.BulkLoader(或类似的方法)将为您提供:
goog.net.BulkLoader.prototype.finishLoad(用于完成所有调用)通过调用相同的函数来检查所有AJAX调用是否完成,这很容易解决。您只需在函数之间共享一个简单的队列,并快速检查(无循环、计时器、承诺等)
//我们将为其发出异步请求的URL列表
var queue=['/something.json','/other.json'];
//将包含我们的返回数据,以便我们可以使用它
//在我们最后的统一回调中(本例中为“displayAll”)
var数据=[];
//处理队列,分派请求,检查是否完成
函数processQueue(队列){
对于(变量i=0;i
编辑:我应该补充一点,我专门针对队列中任意数量的项目。您只需添加另一个URL,效果也一样。通过调用相同的函数来检查所有AJAX调用是否完成,这很容易解决。您只需在函数之间共享一个简单的队列,并进行快速检查(没有循环、计时器、承诺等)
//我们将为其发出异步请求的URL列表
var queue=['/something.json','/other.json'];
//将包含我们的返回数据,以便我们可以使用它
//在我们最后的统一回调中(本例中为“displayAll”)
var数据=[];
//处理队列,分派请求,检查是否完成
函数processQueue(队列){
对于(变量i=0;i