as explained in detail here

you will need to refactor your code.

somehow it seems that it is not the correct way to use recursion within a asynchronous (often delayed) function to search a tree-based or hierarchical data model.

I think this should be the way to do it:

Seperatate the logic into several functions Use "lazy loading" to avoid duplicate call of getChilden() Use recursion and define a new nested function callback Refactor the for-loop to recursion as well

See my untested code to show what I mean:

function compare(lhs, rhs, callback, index, lhsChilds, rhsChilds){ // Not equal if one is a bookmark and another is a folder if (('url' in lhs) != ('url' in rhs)) { callback(false); return; } // If both are bookmarks, compare url and title if ('url' in lhs && 'url' in rhs) { callback(lhs.title == rhs.title && lhs.url == rhs.url); return; } // If both are folders, check parameters and compare contents //First, check if the list has already been loaded (code is running inside a recursive step) if(lhsChilds != undefined && rhsChilds != undefined){ compareTwoChilds(lhs, rhs, callback, index, lhsChilds, rhsChilds); } else{ index = 0; //first recursion for this tuple (lhs, rhs) chrome.bookmarks.getChildren(lhs.id, function (lhsChildren) { chrome.bookmarks.getChildren(rhs.id, function (rhsChildren) { compareTwoChilds(lhs, rhs, callback, index, lhsChilds, rhsChilds); }); }); } } function compareTwoChilds(lhs, rhs, callback, index, lhsChilds, rhsChilds){ if (index < lhsChildren.length){ //just for the safety if (lhsChildren.length != rhsChildren.length) { callback(false); return; } lhsChildren.sort(titleComparator); rhsChildren.sort(titleComparator); //compare using recursion, with an emtpy lists of rhs and lhs children compare(lhsChildren[index], rhsChildren[index], function(compareResult){ if(!compareResult){ callback(false); //if the result is false, no more search needed }else{ // use recursion again to loop through the next childs using the already loaded childs if (++index < lhsChildren.length){ compare(lhsChildren[index], rhsChildren[index], callback, index, lhsChilds, rhsChilds) }else{ callback(true); // the loop has ended, } } }); }else{ callback(false); //this should never happen, so not the same... } }

you can call the compare function like that: