Я хочу сделать три вызова ajax в событии щелчка. Каждый вызов ajax выполняет отдельную операцию и возвращает данные, необходимые для окончательного обратного вызова. Сами вызовы не зависят друг от друга, все они могут выполняться одновременно, однако я хотел бы иметь последний обратный вызов, когда все три будут выполнены.
$('#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+, вы можете использовать отложенный метод, как описано в другом ответе:
Пример отложенного здесь
для jQuery <1.5 будет работать следующее, или если вам нужно, чтобы ваши вызовы ajax запускались в неизвестное время, как показано здесь, с двумя кнопками: запускается после нажатия обеих кнопок
[использование]
для одного обратного вызова после завершения: Рабочий пример
у каждого из них будет свой обратный вызов, когда все будет выполнено: Рабочий пример
[Код]
источник
setCallback
чтобы добавить больше в очередь. Хотя теперь, когда я думаю об этом ... я должен назвать этоaddCallback
или что-то в этом роде ... а не просто установить, так как он добавляется в очередьsingleCallback
нужна ли переменная во второй строке? Или я что-то упустил?Похоже, у вас есть ответы на этот вопрос, однако я думаю, что здесь стоит упомянуть кое-что, что значительно упростит ваш код. jQuery представил
$.when
в v1.5. Это выглядит как:Не видел здесь упомянутого, надеюсь, это поможет.
источник
Сам не вижу необходимости в каком-либо объекте. Просто есть переменная, которая является целым числом. Когда вы начинаете запрос, увеличивайте число. Когда один завершится, уменьшите его. Когда он равен нулю, запросы отсутствуют, так что все готово.
источник
if (!--inProgress)
. Правильная версия аналогичнаinProgress = inProgress - 1; if (inProgress == 0) { /* do stuff */ }
. Компактная форма комбинирует префиксный оператор декремента (--
) и оператор отрицания (!
), чтобы получить значение «истина» (и, следовательно, выполнитьif
блок), еслиinProgress
результат декрементаinProgress == 0
, и получить значение «ложь» (и, следовательно, ничего не делать) в противном случае.Стоит отметить, что, поскольку
$.when
ожидает, что все запросы ajax будут последовательными аргументами (а не массивом), вы обычно увидите$.when
использовать.apply()
такие:Это потому что
$.when
принимает такие аргументыИ не так:
источник
all
метод или что-то подобное, но мне нравится концепция карты. Ницца.Мне нравится идея hvgotcodes. Я предлагаю добавить универсальный инкремент, который сравнивает полное число с необходимым числом, а затем выполняет последний обратный вызов. Это может быть встроено в последний обратный вызов.
[Отредактировано с учетом обновленных названий.]
источник
ИЗМЕНИТЬ - возможно, лучшим вариантом было бы создать конечную точку службы, которая делает все, что делают три запроса. Таким образом, вам нужно выполнить только один запрос, и все данные будут там, где вам нужно, в ответе. Если вы обнаружите, что выполняете одни и те же 3 запроса снова и снова, вы, вероятно, захотите пойти по этому пути. Часто хорошим дизайнерским решением является установка на сервере фасадной службы, которая объединяет вместе часто используемые более мелкие серверные действия. Просто идея.
один из способов сделать это - создать объект «sync» в обработчике кликов перед вызовами ajax. Что-то вроде
Синхронизация будет автоматически привязана к области успешных вызовов (закрытие). В обработчике успеха вы увеличиваете счетчик, и если он равен 3, вы можете вызвать другую функцию.
В качестве альтернативы вы можете сделать что-то вроде
при каждом успешном выполнении значение в синхронизации изменится на true. Перед продолжением вам нужно будет проверить синхронизацию, чтобы убедиться, что все три верны.
Обратите внимание на случай, когда один из ваших xhrs не возвращает успех - вы должны это учитывать.
Еще один вариант - всегда вызывать последнюю функцию в ваших обработчиках успеха и иметь доступ к опции синхронизации, чтобы определить, действительно ли что-то делать. Однако вам нужно будет убедиться, что синхронизация находится в рамках этой функции.
источник
Некоторое время назад я задал тот же вопрос и получил здесь пару хороших ответов: Лучший способ добавить «обратный вызов» после серии асинхронных вызовов XHR
источник
Я получил несколько хороших подсказок из ответов на этой странице. Я немного адаптировал его для себя и подумал, что могу поделиться.
Здесь есть некоторые ограничения, но в моем случае это было нормально. Я также обнаружил, что для более сложных вещей есть также плагин AOP (для jQuery), который может быть полезен: http://code.google.com/p/jquery-aop/
источник
Я столкнулся с этой проблемой сегодня, и это была моя наивная попытка до того, как посмотреть принятый ответ.
источник
Это не jquery (и, похоже, у jquery есть работоспособное решение), а просто как еще один вариант ....
У меня были похожие проблемы, когда я много работал с веб-службами SharePoint - вам часто нужно извлекать данные из нескольких источников для создания входных данных для одного процесса.
Чтобы решить эту проблему, я встроил такую функциональность в свою библиотеку абстракций AJAX. Вы можете легко определить запрос, который будет запускать набор обработчиков по завершении. Однако каждый запрос может быть определен с помощью нескольких HTTP-вызовов. Вот компонент (и подробная документация):
DPAJAX на DepressedPress.com
Этот простой пример создает один запрос с тремя вызовами, а затем передает эту информацию в порядке вызова одному обработчику:
Обратите внимание, что в отличие от многих других решений (в том числе, я считаю, что решение «когда» в jquery) при условии, что этот метод не вызывает однопоточную обработку выполняемых вызовов - каждое из них по-прежнему будет выполняться так быстро (или так медленно), как позволяет среда. но единственный обработчик будет вызываться только тогда, когда все будут завершены. Он также поддерживает установку значений тайм-аута и повторных попыток, если ваша служба немного нестабильна.
Я нашел его безумно полезным (и невероятно простым для понимания с точки зрения кода). Больше никаких цепочек, никаких подсчетов вызовов и сохранения вывода. Просто «установи и забудь».
источник
Хорошо, это устарело, но позвольте мне поделиться своим решением :)
Он также работает с функциями, у которых есть обратный вызов. Вы устанавливаете syncCount и вызываете функцию sync (...) в обратном вызове каждого действия.
источник
Я нашел более простой способ сделать это без необходимости в дополнительных методах организации очереди.
JS
PHP (ajax1.php)
PHP (ajax2.php)
источник
По умолчанию все запросы отправляются асинхронно (т. Е. По умолчанию установлено значение true). Если вам нужны синхронные запросы, установите эту опцию на
false
. Междоменные запросы иdataType: "jsonp"
запросы не поддерживают синхронную работу. Обратите внимание, что синхронные запросы могут временно блокировать браузер, отключая любые действия, когда запрос активен. Начиная с jQuery 1.8 , использованиеasync: false
с jqXHR ($.Deferred
) не рекомендуется; вы должны использовать параметры обратного вызова success / error / complete вместо соответствующих методов объекта jqXHR, таких какjqXHR.done()
или устаревшиеjqXHR.success()
.источник
Извините, но я не могу объяснить, что я боялся, потому что я кореец, который не может сказать ни слова по-английски. но я думаю, вы легко это поймете.
источник