클릭 이벤트에서 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는 $.when
v1.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 옵션에 액세스하여 실제로 어떤 작업을 수행할지 여부를 결정하는 것입니다. 그래도 동기화가 해당 기능의 범위 내에 있는지 확인해야합니다.