[英]Ajax Request Wait Until First AJAX Call not complete
我有以下代碼用於自動保存,但我同時有很多Ajax請求被觸發,我想等待Ajax請求直到第一個Ajax請求未完成
window.submitting = false;
$('form#AddForm').submit(function() {
window.submitting = true;
});
var timeoutId;
$('form input, form textarea, form select').bind('input propertychange change', function() {
console.log('Change');
if (window.submitting)
return false;
clearTimeout(timeoutId);
timeoutId = setTimeout(function() {
// Runs 5 second (5000 ms)
autoSave();
}, 5000);
});
function autoSave() {
$.ajax({
type: "POST",
data: $('form#AddForm').serialize() + '&autosave=true',
beforeSend: function(xhr) {
// Let them know we are saving
console.log('Saving........');
},
success: function(data) {
var jqObj = jQuery(data); // Ajax call here.
var ProductId = jqObj.find("#ProductId").val();
var url = $(location).attr('href');
var split = url.split("add");
if (ProductId) {
history.pushState({}, null, split[0] + "add/" + ProductId);
$('#ProductId').val(ProductId);
$('form#AddForm').attr('action', '/dataproducts/add/' + ProductId);
}
},
});
}
看起來我已經抓住了你的問題。 如果用戶在表單元素上觸發了很少的更改事件,則會創建新的ajax請求,但在上一個處理過程之前不應該創建。
我猜您可以使用下一種方法:在發送ajax之前從表單元素取消綁定偵聽器 ,並在完成ajax時綁定它們 。
有關綁定/解除綁定的SO有一個很好的答案: 在jQuery中刪除事件處理程序的最佳方法是什么?
所以基本上你必須進行litle重構並添加幾行代碼:
window.submitting = false;
$('form#ProductAddForm').submit(function() {
window.submitting = true;
});
var timeoutId;
var saveHandler = function() {
console.log('Change');
if (window.submitting)
return false;
clearTimeout(timeoutId);
timeoutId = setTimeout(function() {
// Runs 5 second (5000 ms)
autoSave();
}, 5000);
};
$('form input, form textarea, form select').bind('input propertychange change', saveHandler);
function autoSave() {
// unbind events
$('form input, form textarea, form select').unbind('input propertychange change')
$.ajax({
type: "POST",
data: $('form#ProductAddForm').serialize() + '&autosave=true',
beforeSend: function(xhr) {
// Let them know we are saving
console.log('Saving........');
},
success: function(data) {
var jqObj = jQuery(data); // Ajax call here.
var ProductId = jqObj.find("#ProductId").val();
var url = $(location).attr('href');
var split = url.split("add");
if (ProductId) {
history.pushState({}, null, split[0] + "add/" + ProductId);
$('#ProductId').val(ProductId);
$('form#ProductAddForm').attr('action', '/account/products/add/' + ProductId);
}
// bind events back
$('form input, form textarea, form select').bind('input propertychange change', saveHandler);
},
error: function{
// bind events back even if reqeust fail
$('form input, form textarea, form select').bind('input propertychange change', saveHandler);
}
});
}
注意不推薦使用jqXHR.success
和jqXHR.error
,有關詳細信息,請參閱$ .ajax 。 另外我添加了error
方法,因為如果ajax失敗,你不能錯過綁定監聽器...
我可能誤解了這個問題,但我讀到了這樣的問題:
我不希望同時運行多個ajax請求。 但是當請求完成后,我想運行下一個請求。
你可以使用ajaxManager,就像jAndy在這里建議的那樣 : 使用jQuery.queue()排隊ajax請求
var ajaxManager = (function() {
var requests = [];
return {
addReq: function(opt) {
requests.push(opt);
},
removeReq: function(opt) {
if( $.inArray(opt, requests) > -1 )
requests.splice($.inArray(opt, requests), 1);
},
run: function() {
var self = this,
oriSuc;
if( requests.length ) {
oriSuc = requests[0].complete;
requests[0].complete = function() {
if( typeof(oriSuc) === 'function' ) oriSuc();
requests.shift();
self.run.apply(self, []);
};
$.ajax(requests[0]);
} else {
self.tid = setTimeout(function() {
self.run.apply(self, []);
}, 1000);
}
},
stop: function() {
requests = [];
clearTimeout(this.tid);
}
};
}());
並在您的代碼中使用它:
ajaxManager.run();
function autoSave() {
ajaxManager.addReq({
type: "POST",
data: $('form#ProductAddForm').serialize() + '&autosave=true',
beforeSend: function(xhr) {
// Let them know we are saving
console.log('Saving........');
},
success: function(data) {
var jqObj = jQuery(data); // Ajax call here.
var ProductId = jqObj.find("#ProductId").val();
var url = $(location).attr('href');
var split = url.split("add");
if (ProductId) {
history.pushState({}, null, split[0] + "add/" + ProductId);
$('#ProductId').val(ProductId);
$('form#ProductAddForm').attr('action', '/account/products/add/' + ProductId);
}
},
});
}
這樣您就可以排隊不同的請求。 但是,通過代碼,您似乎總是發送整個表單。 那么,如果下一個請求會發布更准確的值,為什么第一個請求會完成呢? 顯然有理由說你可能想發布每一個變化。 但如果沒有,您可以取消之前的請求並發送另一個請求。
var xhr;
function autoSave() {
if(xhr){
//TODO: Check if there is a current call.
// abort call.
xhr.abort();
}
xhr = $.ajax({
type: "POST",
data: $('form#ProductAddForm').serialize() + '&autosave=true',
beforeSend: function(xhr) {
// Let them know we are saving
console.log('Saving........');
},
success: function(data) {
var jqObj = jQuery(data); // Ajax call here.
var ProductId = jqObj.find("#ProductId").val();
var url = $(location).attr('href');
var split = url.split("add");
if (ProductId) {
history.pushState({}, null, split[0] + "add/" + ProductId);
$('#ProductId').val(ProductId);
$('form#ProductAddForm').attr('action', '/account/products/add/' + ProductId);
}
},
});
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.