简体   繁体   中英

Wait for nested async calls to finish

I have a series of nested async calls that need to finish before my code continues. Function save_part1 calls the sqlite database and returns the rows of interest. For each of those rows, I make an ajax call to a save them remotely.

From what I have read about promises and deferred, I have only seen them being used in the context of ajax calls. And on top of that, it makes my brain hurt.

Question: how do I wait until all the ajax calls have completed before starting 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)
    });
}

As long as you have ajaxCall_item returning the jQuery deferred object, you can have save_part1 return a deferred object, collect the returned promises into an array, call them with $.when and resolve the "promise" once all of the requests have completed. Then you will be able to write: save_part1().then(save_part2); . Here is an untested example:

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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM