2016-02-12 76 views
1

我有一系列需要在我的代码继续之前完成的嵌套异步调用。函数save_part1调用sqlite数据库并返回感兴趣的行。对于这些行中的每一行,我都会调用ajax来远程保存它们。等待嵌套的异步调用完成

从我读过的有关promise和deferred的内容中,我只看到它们被用在ajax调用的上下文中。最重要的是,这让我的大脑受到伤害。

问题:如何在启动save_part2之前等待所有ajax调用完成?

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) 
    }); 
} 
+0

ajaxCall_item是什么样的? –

+0

[如何等待,直到嵌套的异步jQuery AJAX请求已完成?]可能的重复(http://stackoverflow.com/questions/8097516/how-to-wait-until-nested-async-jquery-ajax-requests-have - 完成) – Ageonix

+0

你是否正在寻找解释在http://api.jquery.com/ajaxcomplete/。您可以使用ajaxComplete进行另一个Ajax调用。 – user3509208

回答

1

只要你有ajaxCall_item返回了jQuery Deferred对象,你可以有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; 
}