2016-02-12 85 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; 
}