如何取消/中止 jQuery AJAX 请求?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4551175/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to cancel/abort jQuery AJAX request?
提问by user556673
I've an AJAX request which will be made every 5 seconds. But the problem is before the AJAX request if the previous request is not completed I've to abort that request and make a new request.
我有一个 AJAX 请求,它将每 5 秒发出一次。但问题是在 AJAX 请求之前,如果前一个请求未完成,我必须中止该请求并发出新请求。
My code is something like this, how to resolve this issue?
我的代码是这样的,如何解决这个问题?
$(document).ready(
var fn = function(){
$.ajax({
url: 'ajax/progress.ftl',
success: function(data) {
//do something
}
});
};
var interval = setInterval(fn, 500);
);
回答by Arun P Johny
The jquery ajax method returns a XMLHttpRequestobject. You can use this object to cancel the request.
jquery ajax 方法返回一个XMLHttpRequest对象。您可以使用此对象取消请求。
The XMLHttpRequest has a abortmethod, which cancels the request, but if the request has already been sent to the server then the server will process the requesteven if we abort the request but the client will not wait for/handle the response.
XMLHttpRequest 有一个abort方法,它取消请求,但如果请求已经发送到服务器,那么即使我们中止请求,服务器也会处理请求,但客户端不会等待/处理响应。
The xhr object also contains a readyStatewhich contains the state of the request(UNSENT-0, OPENED-1, HEADERS_RECEIVED-2, LOADING-3 and DONE-4). we can use this to check whether the previous request was completed.
xhr 对象还包含一个readyState,它包含请求的状态(UNSENT-0、OPENED-1、HEADERS_RECEIVED-2、LOADING-3 和 DONE-4)。我们可以用它来检查之前的请求是否完成。
$(document).ready(
var xhr;
var fn = function(){
if(xhr && xhr.readyState != 4){
xhr.abort();
}
xhr = $.ajax({
url: 'ajax/progress.ftl',
success: function(data) {
//do something
}
});
};
var interval = setInterval(fn, 500);
);
回答by Lyon
I know this might be a little late but i experience similar issues where calling the abort method didnt really aborted the request. instead the browser was still waiting for a response that it never uses. this code resolved that issue.
我知道这可能有点晚了,但我遇到了类似的问题,调用 abort 方法并没有真正中止请求。相反,浏览器仍在等待它从未使用过的响应。这段代码解决了这个问题。
try {
xhr.onreadystatechange = null;
xhr.abort();
} catch (e) {}
回答by Taz
When you make a request to a server, have it check to see if a progress is not null (or fetching that data) first. If it is fetching data, abort the previous request and initiate the new one.
当您向服务器发出请求时,请先检查进度是否不为空(或获取该数据)。如果它正在获取数据,则中止前一个请求并启动新的请求。
var progress = null
function fn () {
if (progress) {
progress.abort();
}
progress = $.ajax('ajax/progress.ftl', {
success: function(data) {
//do something
progress = null;
}
});
}
回答by Habeeb Perwad
Why should you abort the request?
为什么要中止请求?
If each request takes more than five seconds, what will happen?
如果每个请求花费的时间超过 5 秒,会发生什么?
You shouldn't abort the request if the parameter passing with the request is not changing. eg:- the request is for retrieving the notification data. In such situations, The nice approach is that set a new request only after completing the previous Ajax request.
如果随请求传递的参数未更改,则不应中止请求。例如:- 请求用于检索通知数据。在这种情况下,最好的方法是在完成之前的 Ajax 请求后才设置新的请求。
$(document).ready(
var fn = function(){
$.ajax({
url: 'ajax/progress.ftl',
success: function(data) {
//do something
},
complete: function(){setTimeout(fn, 500);}
});
};
var interval = setTimeout(fn, 500);
);
回答by zawhtut
You can use jquery-validate.js . The following is the code snippet from jquery-validate.js.
您可以使用 jquery-validate.js 。以下是来自 jquery-validate.js 的代码片段。
// ajax mode: abort
// usage: $.ajax({ mode: "abort"[, port: "uniqueport"]});
// if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort()
var pendingRequests = {},
ajax;
// Use a prefilter if available (1.5+)
if ( $.ajaxPrefilter ) {
$.ajaxPrefilter(function( settings, _, xhr ) {
var port = settings.port;
if ( settings.mode === "abort" ) {
if ( pendingRequests[port] ) {
pendingRequests[port].abort();
}
pendingRequests[port] = xhr;
}
});
} else {
// Proxy ajax
ajax = $.ajax;
$.ajax = function( settings ) {
var mode = ( "mode" in settings ? settings : $.ajaxSettings ).mode,
port = ( "port" in settings ? settings : $.ajaxSettings ).port;
if ( mode === "abort" ) {
if ( pendingRequests[port] ) {
pendingRequests[port].abort();
}
pendingRequests[port] = ajax.apply(this, arguments);
return pendingRequests[port];
}
return ajax.apply(this, arguments);
};
}
So that you just only need to set the parameter modeto abortwhen you are making ajax request.
这样您只需在发出ajax请求时将参数模式设置为中止即可。
Ref:https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.14.0/jquery.validate.js
参考:https: //cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.14.0/jquery.validate.js
回答by mate.gwozdz
Create a function to call your API. Within this function we define request callApiRequest = $.get(...
- even though this is a definition of a variable, the request is called immediately, but now we have the request defined as a variable. Before the request is called, we check if our variable is defined typeof(callApiRequest) != 'undefined'
and also if it is pending suggestCategoryRequest.state() == 'pending'
- if both are true, we .abort()
the request which will prevent the success callback from running.
创建一个函数来调用您的 API。在这个函数中,我们定义了请求callApiRequest = $.get(...
——尽管这是一个变量的定义,请求会被立即调用,但现在我们将请求定义为一个变量。在调用请求之前,我们检查我们的变量是否已定义typeof(callApiRequest) != 'undefined'
以及它suggestCategoryRequest.state() == 'pending'
是否处于挂起状态- 如果两者都为真,我们.abort()
将阻止成功回调运行的请求。
// We need to wrap the call in a function
callApi = function () {
//check if request is defined, and status pending
if (typeof(callApiRequest) != 'undefined'
&& suggestCategoryRequest.state() == 'pending') {
//abort request
callApiRequest.abort()
}
//define and make request
callApiRequest = $.get("https://example.com", function (data) {
data = JSON.parse(data); //optional (for JSON data format)
//success callback
});
}
Your server/API might not support aborting the request (what if API executed some code already?), but the javascript callback will not fire. This is useful, when for example you are providing input suggestions to a user, such as hashtags input.
您的服务器/API 可能不支持中止请求(如果 API 已经执行了一些代码怎么办?),但 javascript 回调不会触发。这很有用,例如,当您向用户提供输入建议时,例如主题标签输入。
You can further extend this function by adding definition of error callback - what should happen if request was aborted.
您可以通过添加错误回调的定义来进一步扩展此功能 - 如果请求中止会发生什么。
Common use-case for this snippet would be a text input that fires on keypress
event. You can use a timeout, to prevent sending (some of) requests that you will have to cancel .abort()
.
此代码段的常见用例是触发keypress
事件的文本输入。您可以使用超时来防止发送您必须取消的(某些)请求.abort()
。
回答by BananaAcid
jQuery: Use this as a starting point - as inspiration. I solved it like this: (this is not a perfect solution, it just aborts the last instance and is WIP code)
jQuery:以此为起点 - 作为灵感。我是这样解决的:(这不是一个完美的解决方案,它只是中止了最后一个实例,并且是 WIP 代码)
var singleAjax = function singleAjax_constructor(url, params) {
// remember last jQuery's get request
if (this.lastInstance) {
this.lastInstance.abort(); // triggers .always() and .fail()
this.lastInstance = false;
}
// how to use Deferred : http://api.jquery.com/category/deferred-object/
var $def = new $.Deferred();
// pass the deferrer's request handlers into the get response handlers
this.lastInstance = $.get(url, params)
.fail($def.reject) // triggers .always() and .fail()
.success($def.resolve); // triggers .always() and .done()
// return the deferrer's "control object", the promise object
return $def.promise();
}
// initiate first call
singleAjax('/ajax.php', {a: 1, b: 2})
.always(function(a,b,c) {console && console.log(a,b,c);});
// second call kills first one
singleAjax('/ajax.php', {a: 1, b: 2})
.always(function(a,b,c) {console && console.log(a,b,c);});
// here you might use .always() .fail() .success() etc.
回答by programmer
You should also check for readyState 0. Because when you use xhr.abort() this function set readyState to 0 in this object, and your if check will be always true - readyState !=4
您还应该检查 readyState 0。因为当您使用 xhr.abort() 时,此函数在此对象中将 readyState 设置为 0,并且您的 if 检查将始终为 true - readyState !=4
$(document).ready(
var xhr;
var fn = function(){
if(xhr && xhr.readyState != 4 && xhr.readyState != 0){
xhr.abort();
}
xhr = $.ajax({
url: 'ajax/progress.ftl',
success: function(data) {
//do something
}
});
};
var interval = setInterval(fn, 500);
);