Last active
April 14, 2016 18:39
-
-
Save rdpoor/dc7064c15d12f03e0207a897304ab553 to your computer and use it in GitHub Desktop.
Walk a tree with Promises
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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