我有一个打开的 jQuery 对话框,然后进行 AJAX 调用。我想这样做,以便如果对话框关闭或按下取消按钮,AJAX 调用将被取消,并且不会调用其回调函数。我可以想出一些方法来使用变量来做到这一点,如下所示:
function doStuff(){
var doCallback = true;
$('#dialog').dialog({
title: 'Dialog Title',
modal: true,
buttons: {
Cancel: function() {
doCallback = false;
doSomethingElse();
}
}
});
$.get('url/url/url', function(data){
if(doCallback){
doTheSuccessThing(data);
}
});
}
但是,不知怎的,这让我感觉很脏,而且它实际上并没有阻止 AJAX 调用完成。是否有内置方法可以取消正在进行的 AJAX 调用?
最佳答案
当我有一个可能被多次触发的回调,但我只想使用最后一个时,我使用此模式:
var resultsXHR, resultsTimer, resultsId=0;
$('input').keyup(function(){
clearTimeout(resultsTimer); // Remove any queued request
if (resultsXHR) resultsXHR.abort(); // Cancel request in progress
resultsTimer = setTimeout(function(){ // Record the queued request
var id = ++resultsId; // Record the calling order
resultsXHR = $.get('/results',function(data){ // Capture request in progress
resultsXHR = null; // This request is done
if (id!=resultsId) return; // A later request is pending
// ... actually do stuff here ...
});
},500); // Wait 500ms after keyup
});
单独的 abort()
不足以阻止调用成功回调;即使您尝试取消请求,您可能仍然会发现回调正在运行。这就是为什么有必要使用 resultsId
跟踪器,并在另一个稍后的重叠回调准备就绪时让您的回调停止处理。
考虑到这是多么常见和麻烦,我认为以可重用的方式包装它是一个好主意,不需要您为每个要处理的每个变量提供唯一的三元组局部变量名称:
(function($){
$.fn.bindDelayedGet = function(event,delay,url,dataCallback,dataType,callback){
var xhr, timer, ct=0;
return this.bind(event,function(){
clearTimeout(timer);
if (xhr) xhr.abort();
timer = setTimeout(function(){
var id = ++ct;
xhr = $.get(url,dataCallback && dataCallback(),function(data){
xhr = null;
if (id==ct) callback(data);
},dataType);
},delay);
});
};
})(jQuery);
// In action
var inp = $('#myinput').bindDelayedGet('keyup',400,'/search',
function(){ return {term:inp.val()}; },
'html',
function(html){ $('#searchResults').clear().append(html); }
);
您可以找到上面讨论的更详细的代码 on my website .
关于jquery - 在返回之前取消 jQuery AJAX 调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1434519/