Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/77.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何取消/中止jQuery AJAX请求?_Ajax_Jquery - Fatal编程技术网

如何取消/中止jQuery AJAX请求?

如何取消/中止jQuery AJAX请求?,ajax,jquery,Ajax,Jquery,我有一个AJAX请求,它将每5秒发出一次。但是问题是在AJAX请求之前,如果前一个请求没有完成,我必须中止该请求并发出新的请求 我的代码是这样的,如何解决这个问题 $(document).ready( var fn = function(){ $.ajax({ url: 'ajax/progress.ftl', success: function(data) { //do something

我有一个AJAX请求,它将每5秒发出一次。但是问题是在AJAX请求之前,如果前一个请求没有完成,我必须中止该请求并发出新的请求

我的代码是这样的,如何解决这个问题

$(document).ready(
    var fn = function(){
        $.ajax({
            url: 'ajax/progress.ftl',
            success: function(data) {
                //do something
            }
        });
    };

    var interval = setInterval(fn, 500);
);

jQueryAjax方法返回一个对象。您可以使用此对象取消请求

XMLHttpRequest有一个方法,可以取消请求,但是如果请求已经发送到服务器,那么即使我们中止请求,服务器也会处理请求,但客户端不会等待/处理响应

xhr对象还包含包含请求状态(UNSENT-0、open-1、HEADERS_RECEIVED-2、load-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);
);

为什么要中止请求?

如果每个请求花费的时间超过5秒,会发生什么

如果随请求传递的参数没有更改,则不应中止请求。 请求用于检索通知数据。 在这种情况下,最好的方法是仅在完成前一个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);

);

当您向服务器发出请求时,首先让它检查进度是否为null(或获取该数据)。如果它正在提取数据,则中止上一个请求并启动新的请求

var progress = null

function fn () {    
    if (progress) {
        progress.abort();
    }
    progress = $.ajax('ajax/progress.ftl', {
        success: function(data) {
            //do something
            progress = null;
        }
    });
}
jQuery: 以此作为出发点——作为灵感。 我是这样解决的: (这不是一个完美的解决方案,它只是中止最后一个实例,并且是WIP代码)


您还应该检查readyState 0。因为当您使用xhr.abort()时,此函数将此对象中的readyState设置为0,并且您的if检查将始终为true-readyState=四,

$(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);
); 

我知道这可能有点晚,但我遇到了类似的问题,调用abort方法并没有真正中止请求。相反,浏览器仍在等待它从未使用过的响应。 这段代码解决了这个问题

 try {
        xhr.onreadystatechange = null;
        xhr.abort();
} catch (e) {}

您可以使用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);
    };
}
因此,在发出ajax请求时,只需将参数mode设置为abort

$(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);

);

Ref:

创建一个函数来调用API。在这个函数中,我们定义request
callapirest=$.get(…
)-即使这是一个变量的定义,请求也会立即被调用,但现在我们将请求定义为变量。在调用请求之前,我们会检查变量是否定义为
typeof(callapirest)!='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

    });
}
您的服务器/API可能不支持中止请求(如果API已经执行了一些代码怎么办?),但javascript回调不会启动。例如,当您向用户提供输入建议(如hashtags input)时,这非常有用

您可以通过添加错误回调的定义来进一步扩展此函数—如果请求被中止,将会发生什么情况


此代码段的常见用例是在
按键
事件时触发的文本输入。您可以使用超时来防止发送(某些)必须取消的请求
.abort()

问题的可能重复说明请求应每5秒发生一次,但代码使用500毫秒=0.5秒。@romkyns区别在于上面和下面的属性
readystate
,字符
s
在jQuery 1.5中大写。我想知道如果readystate是“LOADING-3”和我们中止?数据被发送到服务器,并且它是否被处理。我们不知道…:SBtw,我认为readyState检查是不必要的,因为它被延迟了,一旦被解决或拒绝,它将不会运行其他。因此
if(xhr)xhr.abort()
也可以正常工作。W3从未在其文档中使用未大写的
readystate
。它总是大写的
readystate
和jquery(在1.5之前或之后)正确匹配w3规范。@ArunPJohny,你能回答这个问题吗?你复制并粘贴了Arun的答案吗?因为像这样的两个代码块完全相同的可能性,间隔和所有…@user2700923他的帖子不完全相同。他的观点是我们还应该检查readyState 0。不过这会更容易理解作为对Arun回答的适当评论。这是一个坏主意。当开始一个新的呼叫时,你不希望前一个呼叫触发整个事件。使用这种方法可能会得到非常奇怪的结果。