簡體   English   中英

異步遞歸函數結束后的回調

[英]Callback after end of asynchronous recursive function

下面的功能以遞歸方式打印文件夾中的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函數完成處理的任何代碼。

您的異步方法實例可能全部一次執行,並且您不知道事先會有多少個實例。 因此,您必須保留計數,然后在完成最后一個異步方法時使用回調。

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

我最近不得不解決這個問題。 該解決方案類似於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();
    }
  });
}

這有點難看,但應該可以。

您可以執行類似JQFAQ.com的操作 。我正在為將來的使用進行更新。

您可以將所有已完成的調用保存到變量中,並根據要處理的書簽數量進行測試。 當到達末尾時(完成計數等於要處理的書簽數量),然后執行最終功能。

這里有一個類似問題的答案,其中的代碼可以用作指導:

在運行JavaScript代碼之前,如何在jQuery.getScript()中加載可變數量的腳本?

可能是解決此問題的更好方法,但是您可以添加depth參數,例如

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM