Callback after end of asynchronous recursive function
Solution 1
Your asynchronous method instances may all be executing at once, and you don't know how many there will be beforehand. So, you'll have to keep count and then use a callback when the last asynchronous method is done.
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();
});
}
Solution 2
I've recently had to solve this problem. The solution was similar to Eric's, but I found that I needed the count variable to be local to the function. Here's how I would solve this:
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();
}
});
}
It's a bit ugly, but it should work.
Related videos on Youtube
usertest
Updated on June 16, 2020Comments
-
usertest almost 4 years
The function below prints Chrome bookmarks in a folder recursively. How could I alter the below function to call another function after the final recursive loop is processed?
chrome.bookmarks.getChildren()
is asynchronous which makes it difficult to know when the function is done processing everything.Thanks.
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); }); }); }
EDIT: Sorry, I don't think I was clear in the initial code example. I've updated the code to show the problem I'm having with the asynchronous function by calling the function multiple times. I'd like any code after the
printBookmarks
function calls to wait for all theprintBookmarks
functions to finish processing. -
usertest about 13 yearsSorry, I don't think I was clear with my example code. Your code works for a single call to printBookmarks but i'd like to know when all call's to printBookmarks (made asynchronous) are done processing. I've updated my code. Thanks.
-
usertest about 13 yearsI think the problem with that is, I don't know the number of bookmarks that'll be processed until they're actually processed.
-
nischayn22 about 11 yearsand I thought I just invented this one :p
-
thispatchofsky over 8 yearsThank you for this solution. In my case, I had implicit detail in my returning data that indicated it was the final iteration, so I didn't use the count. But loved the callback concept. Thank you!