jQuery AJAX 요청을 취소 / 취소하는 방법은 무엇입니까?


244

5 초마다 AJAX 요청이 발생합니다. 그러나 문제는 AJAX 요청 이전입니다. 이전 요청이 완료되지 않으면 해당 요청을 중단하고 새로운 요청을해야합니다.

내 코드는 다음과 같습니다.이 문제를 해결하는 방법은 무엇입니까?

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

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


5
귀하의 질문에 따르면 요청은 5 초마다 발생해야하지만 코드는 500ms = 0.5 초를 사용합니다.
geon

답변:


355

jquery ajax 메소드는 XMLHttpRequest 객체를 반환 합니다. 이 객체를 사용하여 요청을 취소 할 수 있습니다.

XMLHttpRequest에는 중단 메소드 가있어 요청을 취소하지만 요청이 이미 서버로 전송 된 경우 요청 을 중단하더라도 서버는 요청을 처리 하지만 클라이언트는 응답을 기다리거나 처리하지 않습니다.

xhr 객체에는 요청 상태 (UNSENT-0, OPENED-1, HEADERS_RECEIVED-2, LOADING-3 및 DONE-4) 가 포함 된 readyState 도 포함 됩니다. 이를 사용하여 이전 요청이 완료되었는지 확인할 수 있습니다.

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

60
@romkyns 차이점은 readystate위와 readyState아래 의 속성 이며, 문자 s는 jQuery 1.5에서 대문자로 표시됩니다.
Arun P Johny

readyState가 "LOADING-3"이면 어떻게되는지 궁금해서 중단했습니다. 데이터는 서버로 전송되며 처리 여부입니다. 우리는 모른다 ... : S
inf3rno

7
Btw, readyState 검사는 연기 된 것이기 때문에 불필요하다고 생각합니다. 일단 해결되거나 거부되면 다른 것들은 실행되지 않습니다. 따라서 if (xhr) xhr.abort();잘 작동합니다.
Ciantic

2
W3 readystate는 문서에서 대문자 를 사용하지 않았습니다 . 항상 대문자로 표시 readyState되었으며 jquery (1.5 이전 또는 이후)가 w3 사양과 정확하게 일치합니다.
Arashsoft

@ ArunPJohny, 당신은이 질문을 pls stackoverflow.com/questions/49801146/…
Krishna Jonnalagadda

6

서버에 요청할 때는 먼저 진행률이 null이 아니거나 해당 데이터를 가져 오는지 확인해야합니다. 데이터를 가져 오는 경우 이전 요청을 중단하고 새 요청을 시작하십시오.

var progress = null

function fn () {    
    if (progress) {
        progress.abort();
    }
    progress = $.ajax('ajax/progress.ftl', {
        success: function(data) {
            //do something
            progress = null;
        }
    });
}

5

나는 이것이 조금 늦을 수도 있다는 것을 알고 있지만 abort 메소드를 호출해도 실제로 요청이 중단되지 않는 비슷한 문제가 발생합니다. 대신 브라우저는 여전히 사용하지 않는 응답을 여전히 기다리고있었습니다. 이 코드는 그 문제를 해결했습니다.

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

1

왜 요청을 중단해야합니까?

각 요청이 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);

);

5
이것은 나쁜 생각입니다. 새 통화를 시작할 때 이전 통화에서 전체 이벤트가 시작되는 것을 원하지 않습니다. 이 방법으로 매우 이상한 결과를 얻을 수 있습니다.
Webberig

1

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 요청을 할 때 매개 변수 모드중단 하면됩니다.

참조 : https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.14.0/jquery.validate.js


0

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.

0

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

    });
}

서버 / API가 요청 중단을 지원하지 않을 수 있지만 (API가 이미 일부 코드를 실행 한 경우 어떻게됩니까?) 자바 스크립트 콜백이 실행되지 않습니다. 예를 들어 해시 태그 입력과 같은 입력 제안을 사용자에게 제공 할 때 유용합니다.

오류 콜백의 정의를 추가하여이 기능을 추가로 확장 할 수 있습니다. 요청이 중단 된 경우 어떻게됩니까?

이 스 니펫의 일반적인 사용 사례는 keypress이벤트시 발생하는 텍스트 입력입니다 . 시간 초과를 사용하여 취소해야하는 요청 (일부)을 보내지 못하게 할 수 있습니다 .abort().


-7

또한 readyState 0을 확인해야합니다. xhr.abort ()를 사용할 때이 함수에서이 함수는 readyState를 0으로 설정하고 if 검사는 항상 참입니다-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);
); 

2
Arun의 답변을 복사하여 붙여 넣었습니까? 같은 두 코드 블록의 가능성은 정확히 동일하고 간격과 모든 것입니다.

@ user2700923 그의 게시물은 정확히 동일하지 않습니다. 그의 요점은 readyState 0도 확인해야한다는 것입니다. 그러나 이것은 Arun의 답변에 대한 의견으로 더 적합했을 것입니다.
Stefan
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.