Skip to content

Instantly share code, notes, and snippets.

@rdpoor
Last active April 14, 2016 18:39
Show Gist options
  • Select an option

  • Save rdpoor/dc7064c15d12f03e0207a897304ab553 to your computer and use it in GitHub Desktop.

Select an option

Save rdpoor/dc7064c15d12f03e0207a897304ab553 to your computer and use it in GitHub Desktop.

Revisions

  1. rdpoor revised this gist Apr 14, 2016. 1 changed file with 10 additions and 17 deletions.
    27 changes: 10 additions & 17 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,8 @@
    // Walk a tree using Promises, where the act of fetching a node is asynchronous.
    //
    // This version visits the nodes in the expected order, but the returned Promise
    // resolves before all the nodes have been visited -- see comments near bottom.
    // 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";

    @@ -38,14 +39,18 @@ function walkTree(node_name, visit_fn) {
    visit_fn(node);
    var child_names = childrenNamesOf(node);
    var promises = child_names.map(function(child_name) {
    walkTree(child_name, visit_fn);
    return walkTree(child_name, visit_fn);
    });
    return Promise.all(promises);
    });
    };

    walkTree("pops", function(node) { console.log('visiting ' + nameOf(node)) })
    .then(function(nodes) { console.log('found ' + nodes.length + ' nodes.') })
    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:
    //
    @@ -58,15 +63,3 @@ walkTree("pops", function(node) { console.log('visiting ' + nameOf(node)) })
    // visiting greg
    // visiting andrea
    // found 8 nodes.

    // Actual output is:
    //
    // visiting pops
    // found 3 nodes.
    // visiting chuck
    // visiting george
    // visiting pete
    // visiting emma
    // visiting frank
    // visiting greg
    // visiting andrea
  2. rdpoor created this gist Apr 14, 2016.
    72 changes: 72 additions & 0 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,72 @@
    // Walk a tree using Promises, where the act of fetching a node is asynchronous.
    //
    // This version visits the nodes in the expected order, but the returned Promise
    // resolves before all the nodes have been visited -- see comments near bottom.

    "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) {
    walkTree(child_name, visit_fn);
    });
    return Promise.all(promises);
    });
    };

    walkTree("pops", function(node) { console.log('visiting ' + nameOf(node)) })
    .then(function(nodes) { 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.

    // Actual output is:
    //
    // visiting pops
    // found 3 nodes.
    // visiting chuck
    // visiting george
    // visiting pete
    // visiting emma
    // visiting frank
    // visiting greg
    // visiting andrea