Дождитесь окончания вложенных асинхронных вызовов

У меня есть ряд вложенных асинхронных вызовов, которые нужно завершить, прежде чем мой код продолжится. Функция 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;
}
Другие вопросы по тегам