Отмените вызов jQuery AJAX до его возвращения?
У меня есть диалоговое окно 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?
Ответы
Ответ 1
Хорошо, поэтому, основываясь на предположении использовать объект XmlHttpRequest, возвращаемый функцией $.get, я придумал следующее:
function doStuff(){
var ajaxRequest = $.ajax({
url : 'url/url/url',
type : "GET",
success : function(data){
ajaxRequest = null;
doSuccessStuff(data);
}
});
$('#dialog').dialog({
title: 'Stuff Dialog',
bgiframe: true,
modal: true,
buttons: {
Cancel: function() {
if (ajaxRequest)
ajaxRequest.abort();
doCancelStuff();
}
}
});
}
Кажется, он работает и чувствует себя более чистым для меня.
Ответ 2
Когда у меня есть обратный вызов, который может быть запущен несколько раз, но я хочу использовать только последний, я использую этот шаблон:
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); }
);
Вы можете найти приведенный выше код более подробно на моем веб-сайте.
Ответ 3
В jQuery нет метода, но вы можете просто использовать объект XmlHttpRequest, возвращенный из функций jQuery get/post/ajax.
Из jQuery blog:
// Perform a simple Ajax request
var req = $.ajax({
type: "GET",
url: "/user/list/",
success: function(data) {
// Do something with the data...
// Then remove the request.
req = null;
}
});
// Wait for 5 seconds
setTimeout(function(){
// If the request is still running, abort it.
if ( req ) req.abort();
}, 5000);
Ответ 4
Так кажется, хотя я никогда этого не делал.
$.get
возвращает объект XmlHttpRequest
, который имеет метод abort()
, который вы можете вызвать. Может быть, попробуйте это?
Ответ 5
Если вы помещаете условие в script, вы ajax, где при условии, что true, вы выводите свой html, иначе вы ничего не выводите, тогда вы можете сделать простой, если (html) проверить функцию успеха например:
$.ajax({
type: "GET",
url: "url.php",
data: "data="+data,
success: function(html)
{
if(html){
$("#container").empty().html(html);
}
}
});
в этом примере url.php может выглядеть примерно так:
$data = $_GET['data'];
if($data=="whatever"){
echo "<div>Hello</div>";
}else{}
Это сработало для меня. Я знаю, что это сообщение устарело, но надеюсь, что это поможет кому-то.