Дождитесь окончания вложенных асинхронных вызовов
У меня есть ряд вложенных асинхронных вызовов, которые нужно завершить, прежде чем мой код продолжится. Функция save_part1 вызывает базу данных sqlite и возвращает интересующие строки. Для каждой из этих строк я делаю ajax-вызов, чтобы сохранить их удаленно.
Из того, что я прочитал об обещаниях и отложениях, я видел только их использование в контексте вызовов ajax. И вдобавок ко всему, у меня болит мозг.
Вопрос: как мне дождаться завершения всех вызовов ajax перед запуском save_part2?
function save()
{
save_part1();
//this should only happen after all the ajax calls from save_part1 are complete
save_part2();
}
function save_part1()
{
db.transaction(function (tx) {
tx.executeSql("SELECT * FROM TABLE1", [],
function (transaction, results) {
for (var i = 0; i < results.rows.length; i++)
{
var row = results.rows.item(i);
ajaxCall_item1(row);
}
}, errorHandler)
});
}
function save_part2()
{
db.transaction(function (tx) {
tx.executeSql("SELECT * FROM TABLE2", [],
function (transaction, results) {
for (var i = 0; i < results.rows.length; i++)
{
var row = results.rows.item(i);
ajaxCall_item2(row);
}
}, errorHandler)
});
}
1 ответ
Пока у вас есть ajaxCall_item, возвращающий отложенный объект jQuery, вы можете иметь save_part1
вернуть отложенный объект, собрать возвращенные обещания в массив, вызвать их с $.when
и выполните "обещание" после завершения всех запросов. Тогда вы сможете написать: save_part1().then(save_part2);
, Вот непроверенный пример:
function save() {
save_part1().then(save_part2).fail(function(err) {
// ohno
});
}
function ajaxCall_item1(row) {
return $.ajax({ ... });
}
function save_part1()
{
var dfd = jQuery.Deferred();
var promises = [];
db.transaction(function (tx) {
tx.executeSql("SELECT * FROM TABLE1", [],
function (transaction, results) {
for (var i = 0; i < results.rows.length; i++) {
var row = results.rows.item(i);
promises.push(ajaxCall_item1(row));
}
$.when.apply($, promises).then(function() {
dfd.resolve.apply(dfd, arguments);
});
}, function(err) {
dfd.reject(err);
});
});
return dfd;
}