Câu trả lời:
Mỗi khi bạn tạo một yêu cầu ajax, bạn có thể sử dụng một biến để lưu trữ nó:
var request = $.ajax({
type: 'POST',
url: 'someurl',
success: function(result){}
});
Sau đó, bạn có thể hủy bỏ yêu cầu:
request.abort();
Bạn có thể sử dụng một mảng theo dõi tất cả các yêu cầu ajax đang chờ xử lý và hủy bỏ chúng nếu cần thiết.
Đoạn mã sau cho phép bạn duy trì một danh sách ( nhóm ) yêu cầu và hủy bỏ tất cả chúng nếu cần. Tốt nhất để đặt vào <HEAD>
html của bạn, trước khi bất kỳ cuộc gọi AJAX nào khác được thực hiện.
<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'
? Tôi nghi ngờ nó có thể là stackoverflow.com/a/2608601/181971 hoặc có thể chỉ đơn giản là trao đổi thành stackoverflow.com/a/2608618/181971 ?
Sử dụng ajaxSetup là không chính xác , như được lưu ý trên trang tài liệu của nó. Nó chỉ thiết lập mặc định và nếu một số yêu cầu ghi đè lên chúng sẽ có một mớ hỗn độn.
Tôi đến bữa tiệc muộn, nhưng chỉ để tham khảo trong tương lai nếu ai đó đang tìm giải pháp cho cùng một vấn đề, đây là cách của tôi, lấy cảm hứng và phần lớn giống với các câu trả lời trước, nhưng đầy đủ hơn
// 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);
Đây là những gì tôi đang sử dụng để thực hiện điều đó.
$.xhrPool = [];
$.xhrPool.abortAll = function() {
_.each(this, function(jqXHR) {
jqXHR.abort();
});
};
$.ajaxSetup({
beforeSend: function(jqXHR) {
$.xhrPool.push(jqXHR);
}
});
Lưu ý: _.each của underscore.js có mặt, nhưng rõ ràng là không cần thiết. Tôi chỉ lười biếng và tôi không muốn đổi nó thành $ .each (). 8P
aboutAll
nên loại bỏ các yếu tố từ mảng. Ngoài ra, khi yêu cầu kết thúc, nó sẽ tự xóa khỏi danh sách.
Cung cấp cho mỗi xhr yêu cầu một id duy nhất và lưu trữ tham chiếu đối tượng trong một đối tượng trước khi gửi. Xóa tham chiếu sau khi yêu cầu xhr hoàn thành.
Để hủy tất cả yêu cầu bất cứ lúc nào:
$.ajaxQ.abortAll();
Trả về id duy nhất của yêu cầu bị hủy. Chỉ dành cho mục đích thử nghiệm.
Chức năng làm việc:
$.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;
}
};
})();
Trả về một đối tượng với chức năng duy nhất có thể được sử dụng để thêm nhiều chức năng hơn khi được yêu cầu.
Tôi thấy nó quá dễ dàng cho nhiều yêu cầu.
bước 1: xác định một biến ở đầu trang:
xhrPool = []; // no need to use **var**
step2: đặt beforeSend trong tất cả các yêu cầu ajax:
$.ajax({
...
beforeSend: function (jqXHR, settings) {
xhrPool.push(jqXHR);
},
...
Bước 3: sử dụng bất cứ nơi nào bạn cần:
$.each(xhrPool, function(idx, jqXHR) {
jqXHR.abort();
});
Tôi đã mở rộng câu trả lời của mkm bồ và SpYk3HH ở trên để xhrPool.abort ALL có thể hủy bỏ tất cả các yêu cầu đang chờ xử lý của một url đã cho :
$.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;
});
Việc sử dụng là như nhau ngoại trừ việc abort ALL hiện có thể tùy ý chấp nhận một url làm tham số và sẽ chỉ hủy các cuộc gọi đang chờ xử lý đến url đó
Tôi đã có một số vấn đề với mã của Andy, nhưng nó đã cho tôi một số ý tưởng tuyệt vời. Vấn đề đầu tiên là chúng ta nên bật ra bất kỳ đối tượng jqXHR nào hoàn thành thành công. Tôi cũng đã phải sửa đổi chức năng abort ALL. Đây là mã làm việc cuối cùng của tôi:
$.xhrPool = [];
$.xhrPool.abortAll = function() {
$(this).each(function(idx, jqXHR) {
jqXHR.abort();
});
};
$.ajaxSetup({
beforeSend: function(jqXHR) {
$.xhrPool.push(jqXHR);
}
});
$(document).ajaxComplete(function() {
$.xhrPool.pop();
});
Tôi không thích cách làm ajaxComplete (). Không có vấn đề làm thế nào tôi cố gắng cấu hình .ajaxSetup nó không hoạt động.
Tôi đã cập nhật mã để làm cho nó hoạt động với tôi
$.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);
}
}
});
Ném mũ của tôi vào. Cung cấp abort
và remove
phương pháp chống lại xhrPool
mảng, và không có vấn đề với các phần ajaxSetup
ghi đè.
/**
* 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);
});
Tạo một nhóm tất cả các yêu cầu ajax và hủy bỏ chúng .....
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++]);
}
};
Tốt hơn để sử dụng mã độc lập .....
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++]);
}
};
Cũng quan trọng không kém: giả sử bạn muốn đăng xuất và bạn đang tạo các yêu cầu mới bằng bộ hẹn giờ: vì dữ liệu phiên được đổi mới với mỗi bootstrap mới (có thể bạn có thể nói tôi đang nói về Drupal, nhưng đây có thể là bất kỳ trang web nào sử dụng phiên) .. Tôi đã phải xem qua tất cả các tập lệnh của mình bằng một tìm kiếm và thay thế, vì tôi có rất nhiều thứ đang chạy trong các trường hợp khác nhau: các biến toàn cục ở đầu:
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));
Bất cứ khi nào bạn muốn hủy bỏ tất cả các yêu cầu ajax, bạn chỉ cần gọi đường dây này
Request.AbortAll()
Có một giải pháp giả tôi sử dụng nó để hủy bỏ tất cả các yêu cầu ajax. Giải pháp này được tải lại toàn bộ trang. Giải pháp này rất tốt nếu bạn không muốn gán ID cho từng yêu cầu ajax và nếu bạn thực hiện các yêu cầu ajax bên trong vòng lặp for. Điều này sẽ đảm bảo tất cả các yêu cầu ajax bị giết.
location.reload();
Đây là cách kết nối điều này với bất kỳ nhấp chuột nào (hữu ích nếu trang của bạn đang thực hiện nhiều cuộc gọi AJAX và bạn đang cố điều hướng đi).
$ ->
$.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()