Skip to content

Instantly share code, notes, and snippets.

@rdpoor
Last active April 14, 2016 18:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rdpoor/dc7064c15d12f03e0207a897304ab553 to your computer and use it in GitHub Desktop.
Save rdpoor/dc7064c15d12f03e0207a897304ab553 to your computer and use it in GitHub Desktop.
Walk a tree with Promises
// Walk a tree using Promises, where the act of fetching a node is asynchronous.
//
// This version visits the nodes in the expected order and returns a promise that
// is resolved when the last node is visited. (If you're here from the StackOverflow
// post, the original error was a missing return statement in the call to map())
"use strict";
var family_tree = {
"pops" : { name: "pops", children: ["chuck", "george", "pete"]},
"chuck" : { name: "chuck", children: ["emma", "frank"] },
"george" : { name: "george", children: [] },
"pete" : { name: "pete", children: ["greg", "andrea"] },
"emma" : { name: "emma", children: [] },
"frank" : { name: "frank", children: [] },
"greg" : { name: "greg", children: [] },
"andrea" : { name: "andrea", children: [] },
}
function nameOf(node) { return node.name; }
function childrenNamesOf(node) { return node.children; }
// Return a promise to return a node. Uses a timeout to emulate
// a web lookup (or other asynchronous operation).
function getNodeAsync(node_name) {
return new Promise(function(resolve, reject) {
var node = family_tree[node_name];
if (node === undefined) {
reject('cannot find node named ' + node_name);
} else {
setTimeout(function() { resolve(node); }, 500);
}
});
};
function walkTree(node_name, visit_fn) {
return getNodeAsync(node_name)
.then(function(node) {
visit_fn(node);
var child_names = childrenNamesOf(node);
var promises = child_names.map(function(child_name) {
return walkTree(child_name, visit_fn);
});
return Promise.all(promises);
});
};
var nodes = [];
walkTree("pops", function(node) { console.log('visiting ' + nameOf(node));
nodes.push(node);
})
.then(function() { console.log('found ' + nodes.length + ' nodes.') })
// Expected output is:
//
// visiting pops
// visiting chuck
// visiting emma
// visiting frank
// visiting george
// visiting pete
// visiting greg
// visiting andrea
// found 8 nodes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment