Как заставить код ждать при вызове асинхронных вызовов, таких как Ajax
Я ищу что-то вроде этого
function someFunc() {
callAjaxfunc(); //may have multiple ajax calls in this function
someWait(); // some code which waits until async calls complete
console.log('Pass2');
}
function callAjaxfunc() {
//All ajax calls called here
console.log('Pass1');
}
Что я пробовал?
1 Jquery.when()
пытался использовать его.. он работает нормально. Но не так, как я хочу. $.when
будет ждать, но код рядом с $.when()
будет работать без ожидания. Код внутри do callback
работает только после вызовов ajax
2.
setTimeOut() с глобальным флагом
Я был настолько уверен, что это сработает. Я пробовал как следует.
GlobalFlag = false;
function someFunc()
callAjaxfunc(); //may have multiple ajax calls in this function
setTimeOut(waitFunc, 100); // some which waits until async calls complete
console.log('Pass2');
}
function callAjaxfunc() {
//All ajax calls called here
onAjaxSuccess: function() {
GlobalFlag = true;
};
console.log('Pass1');
}
function waitFunc() {
if (!GlobalFlag) {
setTimeOut(waitFunc, 100);
}
}
По-прежнему не удается получить желаемый результат. Я здесь что-то не так? Это не так?
Результат, который я хотел, должен выглядеть следующим образом
Pass1
Pass2
Невозможно выполнить какую-либо скрипку, поскольку ей нужны вызовы AJAX
EDIT: многие из них предлагали обратные вызовы.. я знаю о них.. но все же код рядом с somewait()
будет выполнен. Я хочу, чтобы браузер полностью прекратил выполнение кода рядом с somewait()
до вызова ajax.. Также может быть плохой практикой, но стоит знать и попробовать, если это возможно...
Ответы
Ответ 1
Использовать обратные вызовы. Что-то вроде этого должно работать на основе вашего образца кода.
function someFunc() {
callAjaxfunc(function() {
console.log('Pass2');
});
}
function callAjaxfunc(callback) {
//All ajax calls called here
onAjaxSuccess: function() {
callback();
};
console.log('Pass1');
}
Это немедленно выведет Pass1
(предполагается, что запрос ajax занимает как минимум несколько микросекунд), затем распечатайте Pass2
, когда выполняется onAjaxSuccess
.
Ответ 2
Почему он не работал для вас, используя Deferred Objects
? Если я не понял что-то, это может сработать для вас.
/* AJAX success handler */
var echo = function() {
console.log('Pass1');
};
var pass = function() {
$.when(
/* AJAX requests */
$.post("/echo/json/", { delay: 1 }, echo),
$.post("/echo/json/", { delay: 2 }, echo),
$.post("/echo/json/", { delay: 3 }, echo)
).then(function() {
/* Run after all AJAX */
console.log('Pass2');
});
};
Смотрите здесь.
UPDATE
На основе вашего ввода кажется, что ваша самая быстрая альтернатива - использовать синхронные запросы. Вы можете установить свойство async
в false
в запросах $.ajax
, чтобы блокировать их. Это повесит ваш браузер, пока запрос не будет завершен.
Примечание. Я не рекомендую это, и я все же считаю, что вы должны исправить свой код в рабочем процессе на основе событий, чтобы не зависеть от него.
Ответ 3
Реальные программисты делают это с помощью семафоров.
У переменной есть значение 0
. Увеличьте его перед каждым вызовом AJAX. Уменьшите его в каждом обработчике успеха и проверьте 0
. Если да, то все готово.
Ответ 4
Если вам нужно подождать, пока вызов ajax не будет завершен, вам нужно сделать синхронный вызов.