계속하기 전에 여러 비동기 호출이 완료 될 때까지 대기
따라서로드되는 페이지가 있으며 jquery.get을 통해 드롭 다운에 값을 채우도록 여러 요청을 보냅니다.
$(function() {
LoadCategories($('#Category'));
LoadPositions($('#Position'));
LoadDepartments($('#Department'));
LoadContact();
};
그런 다음 LoadContact (); 다른 호출을 수행하고 반환하면 양식의 모든 필드를 채 웁니다. 문제는 종종 드롭 다운이 모두 채워지지 않아서 올바른 값으로 설정할 수 없다는 것입니다.
내가 할 수 있어야 할 것은 다른 메서드가 완료되고 콜백이 실행 된 후에 만 LoadContact가 실행되도록하는 것입니다.
그러나 드롭 다운 채우기 콜백 끝에 플래그를 여러 개 넣을 필요는 없습니다. 그런 다음 LoadContact ()를 호출하기 전에 확인하고 재귀 적 setTimeout 호출 확인을 수행해야합니다.
jQuery에 "이 모든 작업이 완료되면 이것을 실행하십시오."라고 말할 수있는 것이 있습니까?
추가 정보 나는이 라인을 따라 무언가를 생각하고있다
$().executeAfter(
function () { // When these are done
LoadCategories($('#Category'));
LoadPositions($('#Position'));
LoadDepartments($('#Department'));
},
LoadContact // Do this
);
... 메서드 실행 중에 발생하는 ajax 호출을 추적하고 모두 완료되면 LoadContact를 호출해야합니다.
해당 함수에서 생성되는 ajax를 가로채는 방법을 알고 있다면 아마도 jQuery 확장을 작성하여이를 수행 할 수있을 것입니다.
내 솔루션
;(function($) {
$.fn.executeAfter = function(methods, callback) {
var stack = [];
var trackAjaxSend = function(event, XMLHttpRequest, ajaxOptions) {
var url = ajaxOptions.url;
stack.push(url);
}
var trackAjaxComplete = function(event, XMLHttpRequest, ajaxOptions) {
var url = ajaxOptions.url;
var index = jQuery.inArray(url, stack);
if (index >= 0) {
stack.splice(index, 1);
}
if (stack.length == 0) {
callback();
$this.unbind("ajaxComplete");
}
}
var $this = $(this);
$this.ajaxSend(trackAjaxSend)
$this.ajaxComplete(trackAjaxComplete)
methods();
$this.unbind("ajaxSend");
};
})(jQuery);
This binds to the ajaxSend event while the methods are being called and keeps a list of urls (need a better unique id though) that are called. It then unbinds from ajaxSend so only the requests we care about are tracked. It also binds to ajaxComplete and removes items from the stack as they return. When the stack reaches zero, it executes our callback, and unbinds the ajaxComplete event.
You can use .ajaxStop()
like this:
$(function() {
$(document).ajaxStop(function() {
$(this).unbind("ajaxStop"); //prevent running again when other calls finish
LoadContact();
});
LoadCategories($('#Category'));
LoadPositions($('#Position'));
LoadDepartments($('#Department'));
});
This will run when all current requests are finished then unbind itself so it doesn't run if future ajax calls in the page execute. Also, make sure to put it before your ajax calls, so it gets bound early enough, it's more important with .ajaxStart()
, but best practice to do it with both.
Expanding on Tom Lianza's answer, $.when()
is now a much better way to accomplish this than using .ajaxStop()
.
The only caveat is that you need to be sure the asynchronous methods you need to wait on return a Deferred object
. Luckily jQuery ajax calls already do this by default. So to implement the scenario from the question, the methods that need to be waited on would look something like this:
function LoadCategories(argument){
var deferred = $.ajax({
// ajax setup
}).then(function(response){
// optional callback to handle this response
});
return deferred;
}
Then to call LoadContact() after all three ajax calls have returned and optionally executed their own individual callbacks:
// setting variables to emphasize that the functions must return deferred objects
var deferred1 = LoadCategories($('#Category'));
var deferred2 = LoadPositions($('#Position'));
var deferred3 = LoadDepartments($('#Department'));
$.when(deferred1, deferred2, deferred3).then(LoadContact);
If you're on Jquery 1.5 or later, I suspect the Deferred object is your best bet: http://api.jquery.com/category/deferred-object/
The helper method, when, is also quite nice: http://api.jquery.com/jQuery.when/
But, I don't want to have to put a bunch of flags in the end of the drop down population callbacks, that I then check, and have to have a recursive setTimeout call checking, prior to calling LoadContact();
No need for setTimeout. You just check in each callback that all three lists are populated (or better setup a counter, increase it in each callback and wait till it's equal to 3) and then call LoadContact from callback. Seems pretty easy to me.
ajaxStop approach might work to, I'm just not very familiar with it.
ReferenceURL : https://stackoverflow.com/questions/2768293/waiting-on-multiple-asynchronous-calls-to-complete-before-continuing
'Programing' 카테고리의 다른 글
장기 실행 자바 스크립트가 브라우저를 잠그지 않도록 방지 (0) | 2021.01.08 |
---|---|
변수 값에서 접미사 #DEN은 무엇을 의미합니까? (0) | 2021.01.08 |
IStructuralEquatable 및 IStructuralComparable은 어떤 문제를 해결합니까? (0) | 2021.01.08 |
iOS 애플리케이션간에 키 체인 데이터를 공유하는 방법 (0) | 2021.01.08 |
동일한 프로젝트에 대해 동시에 여러 git 브랜치를 볼 수 있습니까? (0) | 2021.01.08 |