Given a directional T tree with a variable number of children per node, I would like to find a path of size PATH_SIZE from the "good" nodes, starting with root.
each node has an isGood() method and a getChildren() method, which works as expected.
Simple recursive DFS solutions are as follows: (please correct me if I am wrong)
function findGoodPath(node, depth){ if(!node.isGood()){ return null; } else if (depth==PATH_SIZE){ return [node]; } var children = node.getChildren(); for (var i=0; i<children.length; i++){ var result = findGoodPath(children[i], depth+1); if (result){ return result.concat([node]); } } return null; }
The call to findGoodPath(root, 1) should find the result, if it exists.
Now for the problem : the getChildren() method of the node object is actually an asynchronous method that performs I / O operations behind the scenes. it returns nothing and expects a single callback argument to handle the returned children.
A modified code solution ( WRONG ) might look like this:
function findGoodPath(node, depth){ if(!node.isGood()){ return null; } else if (depth==PATH_SIZE){ return [node]; } node.getChildren(function(children){ for (var i=0; i<children.length; i++){ var result = findGoodPath(children[i], depth+1); if (result){ return result.concat([node]); } } }); }
This solution will not work: all getChildren methods of one child node will be called immediately, so it will actually execute BFS. and, even worse, return statements are associated with an anonymous callback function and will execute after the close function completes.
Clearly, there is a need for some kind of flow control mechanism. What is a simple and elegant solution to this problem?
UPDATE: I accepted Sebastian's answer as it solves this problem with recursion, this is how I presented the question. I also posted an answer that uses the whilst asynchronous library, this is what I used. Sebastian was kind enough to compare the two methods here . (spoiler: identical performance)