[javascript] 모든 jQuery Ajax 요청이 완료 될 때까지 기다리시겠습니까?

모든 jQuery Ajax 요청이 다른 함수 내에서 완료 될 때까지 함수를 기다리려면 어떻게해야합니까?

즉, 다음을 실행하기 전에 모든 Ajax 요청이 완료 될 때까지 기다려야합니다. 그러나 어떻게?



답변

jQuery는 이제이 목적을위한 when 함수 를 정의합니다 .

임의의 수의 Deferred 객체를 인수로 받아들이고 모든 객체가 해결되면 함수를 실행합니다.

즉, 네 개의 ajax 요청을 시작하고 (예를 들어) 완료 될 때 조치를 수행하려는 경우 다음과 같이 수행 할 수 있습니다.

$.when(ajax1(), ajax2(), ajax3(), ajax4()).done(function(a1, a2, a3, a4){
    // the code here will be executed when all four ajax requests resolve.
    // a1, a2, a3 and a4 are lists of length 3 containing the response text,
    // status, and jqXHR object for each of the four ajax calls respectively.
});

function ajax1() {
    // NOTE:  This function must return the value 
    //        from calling the $.ajax() method.
    return $.ajax({
        url: "someUrl",
        dataType: "json",
        data:  yourJsonData,
        ...
    });
}

제 생각에는 깨끗하고 명확한 구문을 만들고 페이지가 개발 될 때 원하지 않는 부작용을 일으킬 수있는 ajaxStart 및 ajaxStop과 같은 전역 변수를 사용하지 마십시오.

얼마나 많은 아약스 인수를 기다려야하는지 모르는 경우 (즉, 가변 개수의 인수를 사용하려는 경우) 여전히 수행 할 수 있지만 조금 까다 롭습니다. 참조 ) $ .when (에 Deferreds의 배열에서 패스를 (그리고 아마도 jQuery를 .when 문제 해결 인수의 변수 번호 ).

ajax 스크립트 등의 실패 모드에 대한 심도있는 제어가 필요한 경우 반환 된 객체를 저장할 수 있습니다 . 원래의 모든 ajax 쿼리를 포함 .when()하는 jQuery Promise 객체입니다. 자세한 성공 / 실패 처리기를 추가하기 위해 .then()또는 전화를 걸 수 있습니다 .fail().


답변

문서에서 모든 ajax 요청이 완료된 시기 를 알고 싶다면 그 수에 관계없이 $ .ajaxStop 이벤트를 다음과 같이 사용하십시오 .

$(document).ajaxStop(function () {
  // 0 === $.active
});

이 경우, 애플리케이션에서 몇 개의 요청이 발생하고 있는지, 나중에 완료 될지, 복잡한 논리를 파헤 치거나 어떤 기능이 HTTP(S)요청을 수행 중인지 찾을 필요도 없습니다 .

$.ajaxStop여기서 HTMLrequst에 의해 수정 될 것으로 생각 되는 모든 노드에 바인딩 될 수도 있습니다.


업데이트 : 구문
을 고수 ES하려면 알려진 방법에 Promise.all 을 사용할 수 있습니다 ajax.

Promise.all([ajax1(), ajax2()]).then(() => {
  // all requests finished successfully
}).catch(() => {
  // all requests finished but one or more failed
})

여기서 흥미로운 점은 함께 모두 작동한다는 것입니다 Promises$.ajax요청.

다음은 jsFiddle 데모입니다.


업데이트 2 : async / await 구문을
사용하는 최신 버전 :

try {
  const results = await Promise.all([ajax1(), ajax2()])
  // do other actions
} catch(ex) { }


답변

내가 찾은 좋은 답변 에 의한 gnarf 내가 찾던 정확히 내 자신을 🙂

jQuery ajaxQueue

//This handles the queues    
(function($) {

  var ajaxQueue = $({});

  $.ajaxQueue = function(ajaxOpts) {

    var oldComplete = ajaxOpts.complete;

    ajaxQueue.queue(function(next) {

      ajaxOpts.complete = function() {
        if (oldComplete) oldComplete.apply(this, arguments);

        next();
      };

      $.ajax(ajaxOpts);
    });
  };

})(jQuery);

그런 다음 다음과 같이 대기열에 ajax 요청을 추가 할 수 있습니다.

$.ajaxQueue({
        url: 'page.php',
        data: {id: 1},
        type: 'POST',
        success: function(data) {
            $('#status').html(data);
        }
    });


답변

ajaxStop이벤트를 사용하십시오 .

예를 들어 100 개의 아약스 요청을 가져 오는 동안 loading … 메시지가 있고 일단로드 된 메시지를 숨기려고한다고 가정 해 봅시다 .

jQuery 문서에서 :

$("#loading").ajaxStop(function() {
  $(this).hide();
});

해당 페이지에서 모든 ajax 요청이 완료 될 때까지 기다립니다.


답변

참고 : 위 답변은이 답변을 작성할 당시 존재하지 않은 기능을 사용합니다. jQuery.when()이 접근법 대신에 사용 하는 것이 좋지만 역사적인 목적으로 답을 남기고 있습니다.

구현 방법은 코드에 따라 다르지만 간단한 카운팅 세마포어로 해결할 수도 있습니다. 간단한 예는 다음과 같습니다.

var semaphore  = 0,     // counting semaphore for ajax requests
    all_queued = false; // bool indicator to account for instances where the first request might finish before the second even starts

semaphore++;
$.get('ajax/test1.html', function(data) {
    semaphore--;
    if (all_queued && semaphore === 0) {
        // process your custom stuff here
    }
});

semaphore++;
$.get('ajax/test2.html', function(data) {
    semaphore--;
    if (all_queued && semaphore === 0) {
        // process your custom stuff here
    }
});

semaphore++;
$.get('ajax/test3.html', function(data) {
    semaphore--;
    if (all_queued && semaphore === 0) {
        // process your custom stuff here
    }
});

semaphore++;
$.get('ajax/test4.html', function(data) {
    semaphore--;
    if (all_queued && semaphore === 0) {
        // process your custom stuff here
    }
});

// now that all ajax requests are queued up, switch the bool to indicate it
all_queued = true;

{async : false}와 같이 작동하지만 브라우저를 잠그고 싶지 않은 경우 jQuery 대기열을 사용하여 동일한 작업을 수행 할 수 있습니다.

var $queue = $("<div/>");
$queue.queue(function(){
    $.get('ajax/test1.html', function(data) {
        $queue.dequeue();
    });
}).queue(function(){
    $.get('ajax/test2.html', function(data) {
        $queue.dequeue();
    });
}).queue(function(){
    $.get('ajax/test3.html', function(data) {
        $queue.dequeue();
    });
}).queue(function(){
    $.get('ajax/test4.html', function(data) {
        $queue.dequeue();
    });
});


답변

자바 스크립트는 이벤트 기반이므로 기다리지 말고 후크 / 콜백을 설정하십시오.

아마도 성공 / 완료 방법을 사용할 수 있습니다. jquery.ajax

또는 .ajaxComplete를 사용할 수 있습니다 .

$('.log').ajaxComplete(function(e, xhr, settings) {
  if (settings.url == 'ajax/test.html') {
    $(this).text('Triggered ajaxComplete handler.');
    //and you can do whatever other processing here, including calling another function...
  }
});

비록 당신은 당신의 아약스 요청이 어떻게 더 정확하게 호출되는지에 대한 의사 코드를 게시해야하지만 …


답변

약간의 해결 방법은 다음과 같습니다.

// Define how many Ajax calls must be done
var ajaxCalls = 3;
var counter = 0;
var ajaxCallComplete = function() {
    counter++;
    if( counter >= ajaxCalls ) {
            // When all ajax calls has been done
        // Do something like hide waiting images, or any else function call
        $('*').css('cursor', 'auto');
    }
};

var loadPersons = function() {
        // Show waiting image, or something else
    $('*').css('cursor', 'wait');

    var url = global.ctx + '/loadPersons';
    $.getJSON(url, function(data) {
            // Fun things
    })
    .complete(function() { **ajaxCallComplete();** });
};

var loadCountries = function() {
    // Do things
    var url = global.ctx + '/loadCountries';
    $.getJSON(url, function(data) {
            // Travels
    })
    .complete(function() { **ajaxCallComplete();** });
};

var loadCities = function() {
    // Do things
    var url = global.ctx + '/loadCities';
    $.getJSON(url, function(data) {
            // Travels
    })
    .complete(function() { **ajaxCallComplete();** });
};

$(document).ready(function(){
    loadPersons();
    loadCountries();
    loadCities();
});

희망은 도움이 될 수 있습니다 …