2011-02-19 85 views
16

下面的函數以遞歸方式在文件夾中打印Chrome書籤。在最後的遞歸循環被處理後,我怎麼能改變下面的函數來調用另一個函數呢? chrome.bookmarks.getChildren()是異步的,這使得很難知道函數何時處理完所有事情。異步遞歸函數結束後回調

謝謝。

for (var i = 0; i < foldersArray.length; i++) { 
     // The loop makes several calls with different folder IDs. 
     printBookmarks(foldersArray[i]); 
    } 

    // I'd like any code here to be run only after the above has 
    //finished processing  

    function printBookmarks(id) { 
     chrome.bookmarks.getChildren(id, function(children) { 
      children.forEach(function(bookmark) { 
       console.debug(bookmark.title); 
       printBookmarks(bookmark.id); 
      }); 
     }); 
    } 

編輯:對不起,我不認爲我是在初始代碼示例中清楚。我更新了代碼,通過多次調用該函數來顯示我在異步函數中遇到的問題。我想要printBookmarks函數調用後的任何代碼等待所有printBookmarks函數完成處理。

回答

0

可能是一個更好的方式去,但你可以在響應添加的深度參數,像

printBookmarks('0', 0); 

function printBookmarks(id, depth) { 
    chrome.bookmarks.getChildren(id, function(children) { 
     children.forEach(function(bookmark) { 
      console.debug(bookmark.title); 
      printBookmarks(bookmark.id, depth + 1); 
     }); 
     if(depth == 0) yourFunction(); 
    });  
} 

編輯評論

這是另一種答案的變化一個稍微不同的方法。

runCount = 0; 
for (var i = 0; i < foldersArray.length; i++) { 
    // The loop makes several calls with different folder IDs. 
    printBookmarks(foldersArray[i]); 
    runCount++; 
} 

while(runCount > 0) { // sleep for 10ms or whatnot} 
// I'd like any code here to be run only after the above has 
// finished processing.  

function printBookmarks(id) { 
    chrome.bookmarks.getChildren(id, function(children) { 
     children.forEach(function(bookmark) { 
      console.debug(bookmark.title); 
      printBookmarks(bookmark.id); 
      runCount--; 
     }); 
    }); 
} 
+0

對不起,我不認爲我清楚我的示例代碼。您的代碼適用於打印書籤的單個調用,但是我想知道何時所有調用printBookmarks(異步)都已完成處理。我更新了我的代碼。謝謝。 – usertest 2011-02-19 06:26:11

25

您的異步方法實例可能都是一次執行的,並且您不知道預先有多少個。所以,你必須保持計數,然後在最後一個異步方法完成時使用回調。

for (var i = 0; i < foldersArray.length; i++) { 
    // The loop makes several calls with different folder IDs. 
    printBookmarks(foldersArray[i], thingsToDoAfter); 
} 

function thingsToDoAfter() { 
    // I'd like any code here to be run only after the above has 
    // finished processing. 
} 

var count = 0; 

function printBookmarks(id, callback) { 
    count++; 
    chrome.bookmarks.getChildren(id, function(children) { 
     children.forEach(function(bookmark) { 
      console.debug(bookmark.title); 
      printBookmarks(bookmark.id, callback); 
     }); 
     count--; 
     if (count === 0 && callback) 
      callback(); 
    }); 
} 
+1

,我想我只是發明了這個:p – nischayn22 2013-04-19 19:22:46

+0

謝謝你的解決方案。就我而言,我在返回的數據中隱含了細節,表明這是最後一次迭代,所以我沒有使用count。但喜歡回調概念。謝謝! – 2015-12-11 18:16:39

2

我最近不得不解決這個問題。該解決方案與Eric的相似,但是我發現我需要count變量作爲函數的本地變量。這是我將如何解決這個問題:

for(var i=0;i<foldersArray.length; i++){ 
    // The loop make's several call's with different folder ID's. 
    var printed_children = 0; 
    printBookmarks(foldersArray[i],function() { 
    printed_children++; 
    if(printed_children == foldersArray.length){ 
     // You know you are done! 
    } 
    }); 
} 
// I'd like any code here to be run only after the above has 
//finished processing. 


function printBookmarks(id,finished_callback) { 
    // the printed_children count is local so that it can keep track of 
    // whether or not this level of recursion is complete and should call 
    // back to the previous level 
    var printed_children = 0; 
    chrome.bookmarks.getChildren(id, function(children) { 
    children.forEach(function(bookmark) { 
     console.debug(bookmark.title); 
     // added a callback function to the printBookmarks so that it can 
     // check to see if all upstream recursions have completed. 
     printBookmarks(bookmark.id,function() { 
     printed_children++; 
     if(printed_children == children.length){ 
      finished_callback(); 
     } 
     }); 
    }); 
    if(children.length == 0){ 
     finished_callback(); 
    } 
    }); 
} 

這有點難看,但它應該工作。

0

你可以做這樣的事情JQFAQ.com。我正在更新以備將來使用。