Как заставить функцию ждать, пока все запросы jQuery Ajax будут выполнены внутри другой функции?
Короче говоря, мне нужно дождаться выполнения всех запросов Ajax, прежде чем я выполню следующий. Но как?
javascript
jquery
ajax
jamietelin
источник
источник
Ответы:
jQuery теперь определяет функцию when для этой цели.
Он принимает любое количество отложенных объектов в качестве аргументов и выполняет функцию, когда все они разрешаются.
Это означает, что если вы хотите инициировать (например) четыре ajax-запроса, а затем выполнить действие, когда они будут выполнены, вы можете сделать что-то вроде этого:
На мой взгляд, это обеспечивает чистый и понятный синтаксис и позволяет избежать использования каких-либо глобальных переменных, таких как ajaxStart и ajaxStop, которые могут иметь нежелательные побочные эффекты по мере развития вашей страницы.
Если вы не знаете заранее, сколько аргументов ajax вам нужно ждать (т.е. вы хотите использовать переменное число аргументов), это все равно можно сделать, но это немного сложнее. См. Передача массива отложенных в $ .when () (и, возможно, jQuery. При устранении неполадок с переменным числом аргументов ).
Если вам необходим более глубокий контроль над режимами сбоев сценариев ajax и т. Д., Вы можете сохранить объект, возвращаемый
.when()
- это объект обещания jQuery, охватывающий все исходные запросы ajax. Вы можете позвонить.then()
или.fail()
на него, чтобы добавить подробные обработчики успеха / неудачи.источник
$.when
возвращаетPromise
объект, который имеет не только более полезные методы.done
. Например, с помощью.then(onSuccess, onFailure)
метода вы можете реагировать, когда оба запроса успешны или хотя бы один из них завершается неудачно.fail
делом. В отличие отdone
,fail
срабатывает сразу при первом сбое и игнорирует оставшиеся отсрочки.onFailure
функция может быть присоединена. Как я указал в комментарии к вопросу ОП: он, возможно, захочет более точно указать, что он имел в виду под словом «сделано». У «Райана Мора» также была очень хорошая точка зрения относительно того факта, что онfail
ведет себя по-разному, так какdone
,Promises
я думаю, нужноЕсли вы хотите знать, когда все
ajax
запросы в вашем документе завершены, независимо от того, сколько их существует, просто используйте событие $ .ajaxStop следующим образом:Обновление:
если вы хотите придерживаться
ES
синтаксиса, то вы можете использовать Promise.all для известныхajax
методов:Интересным моментом здесь является то , что он работает как с
Promises
и$.ajax
запросы.Вот демонстрация jsFiddle .
Обновление 2:
еще более свежая версия, использующая синтаксис async / await :
источник
Я нашел хороший ответ от gnarf , что и искал :)
jQuery ajaxQueue
Затем вы можете добавить ajax-запрос в очередь следующим образом:
источник
Используйте
ajaxStop
событие.Например, предположим, у вас есть сообщение загрузки ... при получении 100 запросов Ajax, и вы хотите скрыть это сообщение после загрузки.
Из документа JQuery :
Обратите внимание, что он будет ожидать выполнения всех запросов ajax на этой странице.
источник
ПРИМЕЧАНИЕ. Приведенные выше ответы используют функции, которых не было на момент написания этого ответа. Я рекомендую использовать
jQuery.when()
вместо этих подходов, но я оставляю ответ для исторических целей.-
Возможно, вы могли бы обойтись простым семафором подсчета, хотя то, как вы его реализуете, будет зависеть от вашего кода. Простой пример будет что-то вроде ...
Если вы хотите, чтобы это работало как {async: false}, но не хотели блокировать браузер, вы можете сделать то же самое с помощью очереди jQuery.
источник
.get()
. Таким образом, по крайней мере, вы не дублируете этот код. Не только это, но и объявлениеfunction(){}
каждый раз выделяет память каждый раз! Довольно плохая практика, если вы можете вызывать статически определенную функцию.javascript основан на событиях, так что вам никогда не следует ждать , вместо этого установите хуки / обратные вызовы
Вы можете, вероятно, просто использовать успех / полные методы jquery.ajax
Или вы можете использовать .ajaxComplete :
хотя вам следует опубликовать псевдокод того, как ваши запросы ajax вызываются, чтобы быть более точными ...
источник
Небольшой обходной путь выглядит примерно так:
Надежда может быть полезной ...
источник
jQuery позволяет вам указать, хотите ли вы, чтобы запрос ajax был асинхронным или нет. Вы можете просто сделать ajax-запросы синхронными, и тогда остальная часть кода не будет выполняться, пока они не вернутся.
Например:
источник
Если вам нужно что-то простое; один раз и сделал обратный звонок
источник
Также вы можете использовать async.js .
Я думаю, что это лучше, чем $ .when, потому что вы можете объединить все виды асинхронных вызовов, которые не поддерживают обещания из коробки, такие как тайм-ауты, вызовы SqlLite и т. Д., А не только запросы ajax.
источник
На основе ответа @BBonifield я написал вспомогательную функцию, чтобы семафорная логика не распространялась на все вызовы ajax.
untilAjax
это служебная функция, которая вызывает функцию обратного вызова, когда все ajaxCalls завершены.ajaxObjs
это массив объектов настройки ajax[http://api.jquery.com/jQuery.ajax/]
.fn
является функцией обратного вызоваПример:
doSomething
функция используетuntilAjax
.источник
Я настоятельно рекомендую использовать $ .when (), если вы начинаете с нуля.
Несмотря на то, что у этого вопроса более миллиона ответов, я все равно не нашел ничего полезного для своего случая. Допустим, вам приходится иметь дело с существующей кодовой базой, которая уже делает несколько вызовов ajax и не хочет вводить сложность обещаний и / или переделывать все это.
Мы можем легко воспользоваться JQuery
.data
,.on
и.trigger
функции , которые были частью JQuery с тех пор навсегда.Codepen
Хорошая вещь о моем решении:
очевидно, от чего точно зависит обратный вызов
функция
triggerNowOrOnLoaded
не заботится, загружены ли уже данные или мы все еще ждем ихэто очень легко подключить его к существующему коду
источник
Я использую проверку размера, когда все загрузки AJAX завершены
источник
Чтобы расширить ответ Алекса, у меня есть пример с переменными аргументами и обещаниями. Я хотел загрузить изображения через ajax и отобразить их на странице после того, как они все загрузятся.
Для этого я использовал следующее:
Обновлено для работы с одним или несколькими URL-адресами: https://jsfiddle.net/euypj5w9/
источник
Как уже упоминалось в других ответах, вы можете
ajaxStop()
подождать, пока все запросы Ajax не будут выполнены.Если вы хотите сделать это для конкретного
ajax()
запроса, лучшее, что вы можете сделать, это использоватьcomplete()
метод внутри определенного запроса ajax:Но, если вам нужно подождать лишь несколько запросов ajax? Используйте замечательные обещания JavaScript, чтобы подождать, пока эти ajax, которые вы хотите ждать, будут выполнены. Я сделал короткий, легкий и понятный пример, чтобы показать вам, как обещания работают с ajax.
Пожалуйста, посмотрите на следующий пример . Я использовал,
setTimeout
чтобы уточнить пример.источник
Я нашел простой способ, используя
shift()
источник
Мое решение заключается в следующем
Работал довольно хорошо. Я пробовал много разных способов сделать это, но я нашел, что это самый простой и наиболее пригодный для повторного использования. Надеюсь, поможет
источник
Посмотрите на мое решение:
1. Вставьте эту функцию (и переменную) в ваш файл JavaScript:
2. Создайте массив с вашими запросами, например так:
3. Создать функцию обратного вызова:
4. Вызвать функцию runFunctionQueue с параметрами:
источник
$.when
не работает для меня,callback(x)
вместо того , чтобыreturn x
работать, как описано здесь: https://stackoverflow.com/a/13455253/10357604источник
Попробуйте так. сделать цикл внутри функции сценария java, чтобы дождаться завершения вызова ajax.
источник
setTimeout()
неtake a sleep
. В этом случае вы просто блокируете все вкладки, пока неdone
станет правдой.done
это никогда не будет правдой, пока цикл while все еще работает. Если цикл while работает, цикл обработки событий не может продолжаться и, следовательно, никогда не будет запускать обратный вызов для успешного выполнения AJAX.