Odpowiedzi:
Za każdym razem, gdy tworzysz żądanie ajax, możesz użyć zmiennej do jej przechowywania:
var request = $.ajax({
type: 'POST',
url: 'someurl',
success: function(result){}
});
Następnie możesz przerwać żądanie:
request.abort();
Możesz użyć tablicy śledzącej wszystkie oczekujące żądania ajax i przerwać je w razie potrzeby.
Poniższy fragment kodu pozwala zachować listę ( pulę ) żądań i przerwać je wszystkie w razie potrzeby. Najlepiej umieścić w <HEAD>
pliku HTML, zanim zostaną wykonane inne wywołania AJAX.
<script type="text/javascript">
$(function() {
$.xhrPool = [];
$.xhrPool.abortAll = function() {
$(this).each(function(i, jqXHR) { // cycle through list of recorded connection
jqXHR.abort(); // aborts connection
$.xhrPool.splice(i, 1); // removes from list by index
});
}
$.ajaxSetup({
beforeSend: function(jqXHR) { $.xhrPool.push(jqXHR); }, // annd connection to list
complete: function(jqXHR) {
var i = $.xhrPool.indexOf(jqXHR); // get index for current connection completed
if (i > -1) $.xhrPool.splice(i, 1); // removes from list by index
}
});
})
</script>
Object doesn't support property or method 'indexOf'
? Podejrzewam, że może to być stackoverflow.com/a/2608601/181971, a może po prostu zmienić na stackoverflow.com/a/2608618/181971 ?
Korzystanie z ajaxSetup jest nieprawidłowe , jak zaznaczono na stronie dokumentu. Ustawia tylko wartości domyślne, a jeśli niektóre żądania zastąpią je, nastąpi bałagan.
Jestem spóźniony na imprezę, ale tylko w celu odniesienia w przyszłości, jeśli ktoś szuka rozwiązania tego samego problemu, oto moje podejście, inspirowane i w dużej mierze identyczne z poprzednimi odpowiedziami, ale bardziej kompletne
// Automatically cancel unfinished ajax requests
// when the user navigates elsewhere.
(function($) {
var xhrPool = [];
$(document).ajaxSend(function(e, jqXHR, options){
xhrPool.push(jqXHR);
});
$(document).ajaxComplete(function(e, jqXHR, options) {
xhrPool = $.grep(xhrPool, function(x){return x!=jqXHR});
});
var abort = function() {
$.each(xhrPool, function(idx, jqXHR) {
jqXHR.abort();
});
};
var oldbeforeunload = window.onbeforeunload;
window.onbeforeunload = function() {
var r = oldbeforeunload ? oldbeforeunload() : undefined;
if (r == undefined) {
// only cancel requests if there is no prompt to stay on the page
// if there is a prompt, it will likely give the requests enough time to finish
abort();
}
return r;
}
})(jQuery);
Oto, czego aktualnie używam, aby to osiągnąć.
$.xhrPool = [];
$.xhrPool.abortAll = function() {
_.each(this, function(jqXHR) {
jqXHR.abort();
});
};
$.ajaxSetup({
beforeSend: function(jqXHR) {
$.xhrPool.push(jqXHR);
}
});
Uwaga: _.each underscore.js jest obecny, ale oczywiście nie jest konieczny. Jestem po prostu leniwy i nie chcę go zmieniać na $ .each (). 8 P.
aboutAll
powinien usunąć elementy z tablicy. Ponadto po zakończeniu żądania powinno ono zostać usunięte z listy.
Nadaj każdemu żądaniu xhr unikalny identyfikator i zapisz odwołanie do obiektu w obiekcie przed wysłaniem. Usuń odwołanie po zakończeniu żądania xhr.
Aby anulować wszystkie żądania w dowolnym momencie:
$.ajaxQ.abortAll();
Zwraca unikalne identyfikatory anulowanego żądania. Tylko do celów testowych.
Funkcja pracy:
$.ajaxQ = (function(){
var id = 0, Q = {};
$(document).ajaxSend(function(e, jqx){
jqx._id = ++id;
Q[jqx._id] = jqx;
});
$(document).ajaxComplete(function(e, jqx){
delete Q[jqx._id];
});
return {
abortAll: function(){
var r = [];
$.each(Q, function(i, jqx){
r.push(jqx._id);
jqx.abort();
});
return r;
}
};
})();
Zwraca obiekt z pojedynczą funkcją, którego można użyć, aby w razie potrzeby dodać więcej funkcji.
Uznałem, że jest to zbyt łatwe do wielu żądań.
krok 1: zdefiniuj zmienną na górze strony:
xhrPool = []; // no need to use **var**
krok 2 : ustaw wcześniej Wyślij we wszystkich żądaniach ajax:
$.ajax({
...
beforeSend: function (jqXHR, settings) {
xhrPool.push(jqXHR);
},
...
krok 3: użyj go, gdziekolwiek potrzebujesz:
$.each(xhrPool, function(idx, jqXHR) {
jqXHR.abort();
});
Rozszerzyłem odpowiedź mkmurray i SpYk3HH powyżej, aby xhrPool.abortAll mógł przerwać wszystkie oczekujące żądania danego adresu URL :
$.xhrPool = [];
$.xhrPool.abortAll = function(url) {
$(this).each(function(i, jqXHR) { // cycle through list of recorded connection
console.log('xhrPool.abortAll ' + jqXHR.requestURL);
if (!url || url === jqXHR.requestURL) {
jqXHR.abort(); // aborts connection
$.xhrPool.splice(i, 1); // removes from list by index
}
});
};
$.ajaxSetup({
beforeSend: function(jqXHR) {
$.xhrPool.push(jqXHR); // add connection to list
},
complete: function(jqXHR) {
var i = $.xhrPool.indexOf(jqXHR); // get index for current connection completed
if (i > -1) $.xhrPool.splice(i, 1); // removes from list by index
}
});
$.ajaxPrefilter(function(options, originalOptions, jqXHR) {
console.log('ajaxPrefilter ' + options.url);
jqXHR.requestURL = options.url;
});
Użycie jest takie samo, z tym wyjątkiem, że abortAll może teraz opcjonalnie zaakceptować adres URL jako parametr i anuluje tylko oczekujące połączenia z tym adresem URL
Miałem pewne problemy z kodem Andy'ego, ale dało mi to świetne pomysły. Pierwszym problemem było to, że powinniśmy usunąć wszystkie obiekty jqXHR, które zostały pomyślnie ukończone. Musiałem także zmodyfikować funkcję abortAll. Oto mój końcowy działający kod:
$.xhrPool = [];
$.xhrPool.abortAll = function() {
$(this).each(function(idx, jqXHR) {
jqXHR.abort();
});
};
$.ajaxSetup({
beforeSend: function(jqXHR) {
$.xhrPool.push(jqXHR);
}
});
$(document).ajaxComplete(function() {
$.xhrPool.pop();
});
Nie podobało mi się robienie rzeczy ajaxComplete (). Bez względu na to, jak próbowałem skonfigurować .ajaxSetup, to nie działało.
Zaktualizowałem kod, aby działał dla mnie
$.xhrPool = [];
$.xhrPool.abortAll = function() {
$(this).each(function(idx, jqXHR) {
jqXHR.abort();
});
$(this).each(function(idx, jqXHR) {
var index = $.inArray(jqXHR, $.xhrPool);
if (index > -1) {
$.xhrPool.splice(index, 1);
}
});
};
$.ajaxSetup({
beforeSend: function(jqXHR) {
$.xhrPool.push(jqXHR);
},
complete: function(jqXHR) {
var index = $.inArray(jqXHR, $.xhrPool);
if (index > -1) {
$.xhrPool.splice(index, 1);
}
}
});
Wrzucam kapelusz. Oferty abort
i remove
metody przeciwko xhrPool
tablicy, i nie jest podatny na problemy z ajaxSetup
przesłonięciami.
/**
* Ajax Request Pool
*
* @author Oliver Nassar <onassar@gmail.com>
* @see http://stackoverflow.com/questions/1802936/stop-all-active-ajax-requests-in-jquery
*/
jQuery.xhrPool = [];
/**
* jQuery.xhrPool.abortAll
*
* Retrieves all the outbound requests from the array (since the array is going
* to be modified as requests are aborted), and then loops over each of them to
* perform the abortion. Doing so will trigger the ajaxComplete event against
* the document, which will remove the request from the pool-array.
*
* @access public
* @return void
*/
jQuery.xhrPool.abortAll = function() {
var requests = [];
for (var index in this) {
if (isFinite(index) === true) {
requests.push(this[index]);
}
}
for (index in requests) {
requests[index].abort();
}
};
/**
* jQuery.xhrPool.remove
*
* Loops over the requests, removes it once (and if) found, and then breaks out
* of the loop (since nothing else to do).
*
* @access public
* @param Object jqXHR
* @return void
*/
jQuery.xhrPool.remove = function(jqXHR) {
for (var index in this) {
if (this[index] === jqXHR) {
jQuery.xhrPool.splice(index, 1);
break;
}
}
};
/**
* Below events are attached to the document rather than defined the ajaxSetup
* to prevent possibly being overridden elsewhere (presumably by accident).
*/
$(document).ajaxSend(function(event, jqXHR, options) {
jQuery.xhrPool.push(jqXHR);
});
$(document).ajaxComplete(function(event, jqXHR, options) {
jQuery.xhrPool.remove(jqXHR);
});
Utwórz pulę wszystkich żądań ajax i przerwij je .....
var xhrQueue = [];
$(document).ajaxSend(function(event,jqxhr,settings){
xhrQueue.push(jqxhr); //alert(settings.url);
});
$(document).ajaxComplete(function(event,jqxhr,settings){
var i;
if((i=$.inArray(jqxhr,xhrQueue)) > -1){
xhrQueue.splice(i,1); //alert("C:"+settings.url);
}
});
ajaxAbort = function (){ //alert("abortStart");
var i=0;
while(xhrQueue.length){
xhrQueue[i++] .abort(); //alert(i+":"+xhrQueue[i++]);
}
};
Lepiej używać niezależnego kodu .....
var xhrQueue = [];
$(document).ajaxSend(function(event,jqxhr,settings){
xhrQueue.push(jqxhr); //alert(settings.url);
});
$(document).ajaxComplete(function(event,jqxhr,settings){
var i;
if((i=$.inArray(jqxhr,xhrQueue)) > -1){
xhrQueue.splice(i,1); //alert("C:"+settings.url);
}
});
ajaxAbort = function (){ //alert("abortStart");
var i=0;
while(xhrQueue.length){
xhrQueue[i++] .abort(); //alert(i+":"+xhrQueue[i++]);
}
};
Równie ważne: powiedz, że chcesz się wylogować i generujesz nowe żądania za pomocą timerów: ponieważ dane sesji są odnawiane przy każdym nowym bootstrapie (może możesz powiedzieć, że mówię Drupal, ale może to być każda strona, która używa sesji). Musiałem przejść przez wszystkie moje skrypty z wyszukiwaniem i zamianą, ponieważ miałem mnóstwo rzeczy uruchomionych w różnych przypadkach: zmienne globalne u góry:
var ajReq = [];
var canAj = true;
function abort_all(){
for(x in ajReq){
ajReq[x].abort();
ajReq.splice(x, 1)
}
canAj = false;
}
function rmvReq(ranNum){
var temp = [];
var i = 0;
for(x in ajReq){
if(x == ranNum){
ajReq[x].abort();
ajReq.splice(x, 1);
}
i++;
}
}
function randReqIndx(){
if(!canAj){ return 0; }
return Math.random()*1000;
}
function getReqIndx(){
var ranNum;
if(ajReq.length){
while(!ranNum){
ranNum = randReqIndx();
for(x in ajReq){
if(x===ranNum){
ranNum = null;
}
}
}
return ranMum;
}
return randReqIndx();
}
$(document).ready(function(){
$("a").each(function(){
if($(this).attr('href').indexOf('/logout')!=-1){
$(this).click(function(){
abort_all();
});
}
})
});
// Then in all of my scripts I wrapped my ajax calls... If anyone has a suggestion for a
// global way to do this, please post
var reqIndx = getReqIndx();
if(reqIndx!=0){
ajReq[reqIndx] = $.post(ajax, { 'action': 'update_quantities', iids:iidstr, qtys:qtystr },
function(data){
//..do stuff
rmvReq(reqIndx);
},'json');
}
var Request = {
List: [],
AbortAll: function () {
var _self = this;
$.each(_self.List, (i, v) => {
v.abort();
});
}
}
var settings = {
"url": "http://localhost",
success: function (resp) {
console.log(resp)
}
}
Request.List.push($.ajax(settings));
za każdym razem, gdy chcesz przerwać wszystkie żądania ajax, wystarczy wywołać tę linię
Request.AbortAll()
Istnieje fałszywe rozwiązanie, którego używam do przerywania wszystkich żądań ajax. To rozwiązanie powoduje przeładowanie całej strony. To rozwiązanie jest dobre, jeśli nie chcesz przypisywać identyfikatora do każdego żądania ajax i jeśli tworzysz żądania ajax w pętli for. Dzięki temu wszystkie żądania ajax zostaną zabite.
location.reload();
Oto jak podłączyć to za pomocą dowolnego kliknięcia (przydatne, jeśli twoja strona zawiera wiele wywołań AJAX i próbujesz nawigować dalej).
$ ->
$.xhrPool = [];
$(document).ajaxSend (e, jqXHR, options) ->
$.xhrPool.push(jqXHR)
$(document).ajaxComplete (e, jqXHR, options) ->
$.xhrPool = $.grep($.xhrPool, (x) -> return x != jqXHR);
$(document).delegate 'a', 'click', ->
while (request = $.xhrPool.pop())
request.abort()