Jawaban:
Setiap kali Anda membuat permintaan ajax, Anda bisa menggunakan variabel untuk menyimpannya:
var request = $.ajax({
type: 'POST',
url: 'someurl',
success: function(result){}
});
Kemudian Anda dapat membatalkan permintaan:
request.abort();
Anda bisa menggunakan larik pencatatan array dari semua permintaan ajax yang tertunda dan batalkan jika perlu.
Cuplikan berikut memungkinkan Anda mempertahankan daftar ( kumpulan ) permintaan dan membatalkan semuanya jika diperlukan. Terbaik untuk ditempatkan di <HEAD>
html Anda, sebelum panggilan AJAX lainnya dibuat.
<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'
? Saya menduga itu mungkin stackoverflow.com/a/2608601/181971 atau mungkin hanya bertukar ke stackoverflow.com/a/2608618/181971 ?
Menggunakan ajaxSetup tidak benar , seperti yang dicatat pada halaman . Ini hanya mengatur default, dan jika beberapa permintaan menimpanya, akan ada kekacauan.
Saya jauh terlambat ke pesta, tetapi hanya untuk referensi di masa depan jika seseorang mencari solusi untuk masalah yang sama, inilah tugas saya, terinspirasi oleh dan sebagian besar identik dengan jawaban sebelumnya, tetapi lebih lengkap
// 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);
Inilah yang saya gunakan saat ini untuk mencapai itu.
$.xhrPool = [];
$.xhrPool.abortAll = function() {
_.each(this, function(jqXHR) {
jqXHR.abort();
});
};
$.ajaxSetup({
beforeSend: function(jqXHR) {
$.xhrPool.push(jqXHR);
}
});
Catatan: _.setiap underscore.js ada, tetapi jelas tidak perlu. Saya hanya malas dan saya tidak ingin mengubahnya menjadi $ .each (). 8P
aboutAll
harus menghapus elemen dari array. Plus ketika permintaan selesai, itu harus menghapus sendiri dari daftar.
Berikan setiap permintaan xhr id unik dan simpan referensi objek dalam objek sebelum mengirim. Hapus referensi setelah permintaan xhr selesai.
Untuk membatalkan semua permintaan kapan saja:
$.ajaxQ.abortAll();
Mengembalikan id unik dari permintaan yang dibatalkan. Hanya untuk tujuan pengujian.
Fungsi kerja:
$.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;
}
};
})();
Mengembalikan objek dengan fungsi tunggal yang dapat digunakan untuk menambahkan lebih banyak fungsi saat diperlukan.
Saya merasa terlalu mudah untuk beberapa permintaan.
langkah1: tentukan variabel di bagian atas halaman:
xhrPool = []; // no need to use **var**
step2: atur sebelumKirim dalam semua permintaan ajax:
$.ajax({
...
beforeSend: function (jqXHR, settings) {
xhrPool.push(jqXHR);
},
...
step3: gunakan di mana pun Anda inginkan:
$.each(xhrPool, function(idx, jqXHR) {
jqXHR.abort();
});
Saya memperpanjang jawaban mkmurray dan SpYk3HH di atas sehingga xhrPool.abortAll dapat membatalkan semua permintaan yang tertunda dari url yang diberikan :
$.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;
});
Penggunaannya sama kecuali abortAll yang sekarang secara opsional dapat menerima url sebagai parameter dan hanya akan membatalkan panggilan yang tertunda ke url itu
Saya memiliki beberapa masalah dengan kode andy, tetapi itu memberi saya beberapa ide bagus. Masalah pertama adalah bahwa kita harus menghapus objek jqXHR yang berhasil diselesaikan. Saya juga harus memodifikasi fungsi abortAll. Ini kode kerja terakhir saya:
$.xhrPool = [];
$.xhrPool.abortAll = function() {
$(this).each(function(idx, jqXHR) {
jqXHR.abort();
});
};
$.ajaxSetup({
beforeSend: function(jqXHR) {
$.xhrPool.push(jqXHR);
}
});
$(document).ajaxComplete(function() {
$.xhrPool.pop();
});
Saya tidak suka cara ajaxComplete () dalam melakukan sesuatu. Tidak peduli bagaimana saya mencoba mengkonfigurasi .ajaxSetup itu tidak berfungsi.
Saya telah memperbarui kode untuk membuatnya berfungsi untuk saya
$.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);
}
}
});
Melemparkan topiku. Menawarkan abort
dan remove
metode terhadap xhrPool
array, dan tidak rentan terhadap masalah dengan ajaxSetup
penggantian.
/**
* 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);
});
Buat kumpulan semua permintaan ajax dan batalkan .....
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++]);
}
};
Lebih baik menggunakan kode independen .....
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++]);
}
};
Sama pentingnya: katakanlah Anda ingin keluar dan Anda membuat permintaan baru dengan timer: karena data sesi diperbarui dengan setiap bootstrap baru (mungkin Anda bisa mengatakan saya berbicara Drupal, tetapi ini bisa berupa situs yang menggunakan sesi). Saya harus memeriksa semua skrip saya dengan pencarian dan ganti, karena saya punya banyak hal yang berjalan dalam kasus yang berbeda: variabel global di atas:
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));
setiap kali Anda ingin membatalkan semua permintaan ajax, Anda hanya perlu menghubungi saluran ini
Request.AbortAll()
Ada solusi tiruan yang saya gunakan untuk membatalkan semua permintaan ajax. Solusi ini memuat ulang seluruh halaman. Solusi ini bagus jika Anda tidak suka menetapkan ID untuk setiap permintaan ajax, dan jika Anda membuat permintaan ajax di dalam untuk-loop. Ini akan memastikan semua permintaan ajax terbunuh.
location.reload();
Berikut ini cara menghubungkan ini dengan klik apa pun (berguna jika halaman Anda melakukan banyak panggilan AJAX dan Anda mencoba menavigasi).
$ ->
$.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()