source

jQuery의 모든 활성 Ajax 요청 중지

factcode 2023. 2. 17. 21:41
반응형

jQuery의 모든 활성 Ajax 요청 중지

양식을 제출할 때 모든 활성 Ajax 요청이 실패하여 오류 이벤트가 트리거되는 문제가 있습니다.

오류 이벤트를 트리거하지 않고 jQuery의 모든 활성 Ajax 요청을 중지하려면 어떻게 해야 합니까?

Ajax 요청을 작성할 때마다 변수를 사용하여 저장할 수 있습니다.

var request = $.ajax({
    type: 'POST',
    url: 'someurl',
    success: function(result){}
});

그런 다음 요청을 중단할 수 있습니다.

request.abort();

보류 중인 모든 Ajax 요청을 추적하는 어레이를 사용하고 필요한 경우 중단할 수 있습니다.

다음 스니펫을 사용하면 요청 목록()을 유지하고 필요에 따라 모두 중단할 수 있습니다.최적의 장소<HEAD>다른 AJAX 콜이 발신되기 전에, html을 참조해 주세요.

<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>

ajaxSetup을 사용하는 것은 doc 페이지에 기재되어 있듯이 올바르지 않습니다.디폴트만 설정되며, 일부 요구가 디폴트보다 우선하면 혼란이 발생합니다.

파티에 많이 늦었지만, 만약 누군가가 같은 문제에 대한 해결책을 찾고 있다면, 여기 제가 먼저 말씀드린 답변에서 영감을 얻었고 대체로 비슷하지만, 더 완벽합니다.

// 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);

그 목적을 달성하기 위해 현재 사용하고 있는 것은 다음과 같습니다.

$.xhrPool = [];
$.xhrPool.abortAll = function() {
  _.each(this, function(jqXHR) {
    jqXHR.abort();
  });
};
$.ajaxSetup({
  beforeSend: function(jqXHR) {
    $.xhrPool.push(jqXHR);
  }
});

주의: _.underscore.js는 각각 존재하지만 필수는 아닙니다.귀찮아서 개당 $.8P로 바꾸고 싶지 않습니다.

전송하기 전에 각 xhr 요청에 고유한 ID를 지정하고 개체 참조를 개체에 저장합니다.xhr 요청이 완료된 후 참조를 삭제합니다.

언제든지 모든 요청을 취소하려면:

$.ajaxQ.abortAll();

취소된 요청의 고유 ID를 반환합니다.테스트 목적으로만.

작업 기능:

$.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;
    }
  };

})();

필요할 때 기능을 추가하는 데 사용할 수 있는 단일 기능을 가진 개체를 반환합니다.

여러 번 요청하기에는 너무 쉬웠어요.

1단계: 페이지 맨 위에 변수를 정의합니다.

  xhrPool = []; // no need to use **var**

2단계: set before 모든 Ajax 요청을 전송합니다.

  $.ajax({
   ...
   beforeSend: function (jqXHR, settings) {
        xhrPool.push(jqXHR);
    },
    ...

3단계: 필요한 장소에서 사용:

   $.each(xhrPool, function(idx, jqXHR) {
          jqXHR.abort();
    });

mkmurray와 SpYk3를 확장했습니다.위의 HH에 응답하면 xhrPool.abortAll은 특정 URL의 보류 중인 모든 요구를 중단할 수 있습니다.

$.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;
});

사용방법은 abortAll이 옵션으로 URL을 파라미터로 받아들일 수 있게 되어 해당 URL에 대한 보류 중인 콜만 취소됩니다.

앤디의 코드에 문제가 좀 있었지만, 좋은 생각이 떠올랐어요.첫 번째 문제는 정상적으로 완료된 모든 jqXHR 개체를 팝업해야 한다는 것이었습니다.abortAll 함수도 수정해야 했습니다.마지막 작업 코드는 다음과 같습니다.

$.xhrPool = [];
$.xhrPool.abortAll = function() {
            $(this).each(function(idx, jqXHR) {
                        jqXHR.abort();
                        });
};
$.ajaxSetup({
    beforeSend: function(jqXHR) {
            $.xhrPool.push(jqXHR);
            }
});
$(document).ajaxComplete(function() {
            $.xhrPool.pop();
            });

저는 ajax Complete() 방식을 좋아하지 않았습니다..ajaxSetup은 아무리 설정해도 동작하지 않습니다.

나에게 맞게 코드를 업데이트했습니다.

$.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);
        }
    }
});

모자를 던지다.abort ★★★★★★★★★★★★★★★★★」remove에 메서드xhrPool 「어레이」에 가 생기기 은 아닙니다.ajaxSetup어씁니니다다

/**
 * 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);
});

모든 Ajax 요청의 풀을 만들어 중단합니다.

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++]);
    }
};
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));

모든 Ajax 요청을 중단하려면 이 회선을 호출하기만 하면 됩니다.

Request.AbortAll()

독립된 코드를 사용하는 것이 좋습니다.

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++]);
    }
};

마찬가지로 중요한 것은 로그오프하고 타이머를 사용하여 새로운 요구를 생성한다고 하는 것입니다.세션 데이터는 새로운 부트스트랩마다 갱신되기 때문입니다(Drupal과 대화하고 있다고 말할 수 있습니다만, 이것은 세션을 사용하는 모든 사이트일 수 있습니다).검색과 치환으로 모든 스크립트를 검토해야 했습니다.다양한 경우에서 실행이 가능했기 때문입니다.상단의 글로벌 변수:

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');
}

다음은 모든 Ajax 콜을 리프레시하는 과거 복사 함수입니다.
fillCompteList() ★★★★★★★★★★★★★★★★★」fetchAll() 오브젝트 Ajax를 .

function fillCompteList() {
   return $.ajax({
            url: 'www.somewhere.com' ,
            method: 'GET',
            success: function(res){
            ...
          });

그리고 이걸 이용해서

var xhrPool = [fillCompteList(inisial), fetchAll(params)] ;//old
function refrechAllUsing(SOME , params){
    xhrPool.forEach(function(request){
        request.abort();
    });
    xhrPool = [fillCompteList(SOME), fetchAll(params)]//new with other parameters
    Promise.all(xhrPool).then(() => {
        $('#loadding').undisplay();//remove the loadding screen 

    }).catch(() => {
        warning("Some problem happened");
        $('#loadding').undisplay();//remove the loadding screen 
    });
}

클릭 한 번으로 이것을 접속하는 방법은 다음과 같습니다(페이지에서 많은 AJAX 콜을 발신하고 있고, 다른 페이지로 이동하려고 할 때 유용합니다).

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

모든 ajax 요청을 중단하기 위해 사용하는 더미 솔루션이 있습니다.이 솔루션은 페이지 전체를 새로고침합니다.이 솔루션은 각 Ajax 요청에 ID를 할당하고 싶지 않은 경우 및 for-loop 내에서 Ajax 요청을 하는 경우에 적합합니다.그러면 모든 Ajax 요청이 삭제됩니다.

location.reload();

언급URL : https://stackoverflow.com/questions/1802936/stop-all-active-ajax-requests-in-jquery

반응형