[jquery] 여러 아약스 호출에 대한 jQuery 콜백

클릭 이벤트에서 3 개의 아약스 호출을하고 싶습니다. 각 아약스 호출은 고유 한 작업을 수행하고 최종 콜백에 필요한 데이터를 반환합니다. 전화 자체는 서로 의존하지 않으며 모두 동시에 갈 수 있지만 세 가지가 모두 완료되면 최종 콜백을하고 싶습니다.

$('#button').click(function() {
    fun1();
    fun2();
    fun3();
//now do something else when the requests have done their 'success' callbacks.
});

var fun1= (function() {
    $.ajax({/*code*/});
});
var fun2 = (function() {
    $.ajax({/*code*/});
});
var fun3 = (function() {
    $.ajax({/*code*/});
});



답변

여기에 내가 작성한 콜백 객체가 있습니다. 한 번의 콜백이 모두 완료되면 발생하거나 각각 고유의 콜백이 있고 모두 완료되면 모두 호출하도록 설정할 수 있습니다.

주의

jQuery 1.5 이상부터 다른 답변에 설명 된대로 지연된 메소드를 사용할 수 있습니다.

  $.when($.ajax(), [...]).then(function(results){},[...]);

여기서 연기되는 예

jQuery <1.5의 경우 다음이 작동하거나 두 개의 버튼으로 여기에 표시된 것처럼 알 수없는 시간에 ajax 호출을 시작 해야하는 경우 : 두 버튼을 클릭 한 후 시작

[용법]

에 대한 하나의 완전한 번 콜백 : 작업 예

// initialize here
var requestCallback = new MyRequestsCompleted({
    numRequest: 3,
    singleCallback: function(){
        alert( "I'm the callback");
    }
});

//usage in request
$.ajax({
    url: '/echo/html/',
    success: function(data) {
        requestCallback.requestComplete(true);
    }
});
$.ajax({
    url: '/echo/html/',
    success: function(data) {
        requestCallback.requestComplete(true);
    }
});
$.ajax({
    url: '/echo/html/',
    success: function(data) {
        requestCallback.requestComplete(true);
    }
});

모두 완료되면 각각 자체 콜백이 발생합니다. 작업 예

//initialize 
var requestCallback = new MyRequestsCompleted({
    numRequest: 3
});

//usage in request
$.ajax({
    url: '/echo/html/',
    success: function(data) {
        requestCallback.addCallbackToQueue(true, function() {
            alert('Im the first callback');
        });
    }
});
$.ajax({
    url: '/echo/html/',
    success: function(data) {
        requestCallback.addCallbackToQueue(true, function() {
            alert('Im the second callback');
        });
    }
});
$.ajax({
    url: '/echo/html/',
    success: function(data) {
        requestCallback.addCallbackToQueue(true, function() {
            alert('Im the third callback');
        });
    }
});

[코드]

var MyRequestsCompleted = (function() {
    var numRequestToComplete, requestsCompleted, callBacks, singleCallBack;

    return function(options) {
        if (!options) options = {};

        numRequestToComplete = options.numRequest || 0;
        requestsCompleted = options.requestsCompleted || 0;
        callBacks = [];
        var fireCallbacks = function() {
            alert("we're all complete");
            for (var i = 0; i < callBacks.length; i++) callBacks[i]();
        };
        if (options.singleCallback) callBacks.push(options.singleCallback);

        this.addCallbackToQueue = function(isComplete, callback) {
            if (isComplete) requestsCompleted++;
            if (callback) callBacks.push(callback);
            if (requestsCompleted == numRequestToComplete) fireCallbacks();
        };
        this.requestComplete = function(isComplete) {
            if (isComplete) requestsCompleted++;
            if (requestsCompleted == numRequestToComplete) fireCallbacks();
        };
        this.setCallback = function(callback) {
            callBacks.push(callBack);
        };
    };
})();


답변

이것에 대한 답변이있는 것처럼 보이지만 여기에 언급 할 가치가있어 코드를 크게 단순화 할 수 있다고 생각합니다. jQuery는 $.whenv1.5에서 도입되었습니다 . 다음과 같습니다.

$.when($.ajax(...), $.ajax(...)).then(function (resp1, resp2) {
    //this callback will be fired once all ajax calls have finished.
});

여기에 언급되지 않은 것이 도움이 되길 바랍니다.


답변

어떤 물체에 대한 필요성도 알지 못합니다. 단순은 정수인 변수를 갖습니다. 요청을 시작할 때 숫자를 늘리십시오. 완료되면 줄이십시오. 값이 0이면 진행중인 요청이 없으므로 완료된 것입니다.

$('#button').click(function() {
    var inProgress = 0;

    function handleBefore() {
        inProgress++;
    };

    function handleComplete() {
        if (!--inProgress) {
            // do what's in here when all requests have completed.
        }
    };

    $.ajax({
        beforeSend: handleBefore,
        complete: function () {
            // whatever
            handleComplete();
            // whatever
        }
    });
    $.ajax({
        beforeSend: handleBefore,
        complete: function () {
            // whatever
            handleComplete();
            // whatever
        }
    });
    $.ajax({
        beforeSend: handleBefore,
        complete: function () {
            // whatever
            handleComplete();
            // whatever
        }
    });
});


답변

주목할 그것은의 가치가 그 이후 $.when모든 순차적 인수로 아약스 요청 (안 배열)를 흔히 볼 수 있습니다에게 기대 $.when와 함께 사용 .apply()과 같이 :

// Save all requests in an array of jqXHR objects
var requests = arrayOfThings.map(function(thing) {
    return $.ajax({
        method: 'GET',
        url: 'thing/' + thing.id
    });
});
$.when.apply(this, requests).then(function(resp1, resp2/*, ... */) {
    // Each argument is an array with the following structure: [ data, statusText, jqXHR ]
    var responseArgsArray = Array.prototype.slice.call(this, arguments);

});

이것은 이와 $.when같은 인수를 허용 하기 때문입니다

$.when(ajaxRequest1, ajaxRequest2, ajaxRequest3);

그리고 이것처럼 :

$.when([ajaxRequest1, ajaxRequest2, ajaxRequest3]);


답변

나는 hvgotcodes의 아이디어를 좋아합니다. 내 제안은 완료 수를 필요한 수와 비교 한 다음 최종 콜백을 실행하는 일반 증분기를 추가하는 것입니다. 이것은 최종 콜백에 내장 될 수 있습니다.

var sync = {
 callbacksToComplete = 3,
 callbacksCompleted = 0,
 addCallbackInstance = function(){
  this.callbacksCompleted++;
  if(callbacksCompleted == callbacksToComplete) {
   doFinalCallBack();
  }
 }
};

[이름 업데이트를 반영하도록 편집되었습니다.]


답변

편집-아마도 가장 좋은 옵션은 세 가지 요청이하는 모든 작업을 수행하는 서비스 엔드 포인트를 만드는 것입니다. 그렇게하면 하나의 요청 만하면됩니다. 모든 데이터는 응답에 필요한 곳입니다. 동일한 3 번의 요청을 반복해서 반복하는 경우이 경로를 사용하고 싶을 것입니다. 일반적으로 작은 서버 작업을 함께 사용하는 서버에 파사드 서비스를 설정하는 것이 좋은 설계 결정입니다. 그냥 생각이야


이를 수행하는 한 가지 방법은 ajax 호출 전에 클릭 핸들러에서 ‘동기화’객체를 만드는 것입니다. 같은 것

var sync = {
   count: 0
}

동기화는 성공 호출 범위에 자동으로 연결됩니다 (폐쇄). 성공 처리기에서는 개수를 늘리고 3이면 다른 함수를 호출 할 수 있습니다.

또는, 당신은 같은 것을 할 수 있습니다

var sync = {
   success1Complete: false,
   ...
   success3Complete: false,
}

성공할 때마다 동기화의 값이 true로 변경됩니다. 계속하기 전에 동기화를 확인하여 세 가지가 모두 맞는지 확인해야합니다.

xhr 중 하나가 성공을 반환하지 않는 경우를 고려해야합니다.

또 다른 옵션은 항상 성공 처리기에서 최종 함수를 호출하고 sync 옵션에 액세스하여 실제로 어떤 작업을 수행할지 여부를 결정하는 것입니다. 그래도 동기화가 해당 기능의 범위 내에 있는지 확인해야합니다.


답변

나는 얼마 전에 같은 질문을했고 여기에 몇 가지 좋은 답변을 얻었습니다 : 일련의 비동기 XHR 호출 후 ‘콜백’을 추가하는 가장 좋은 방법