asynchronous recursion: processing a tree

Processing a tree of nodes, each children must be processed before its parent. A parent can only be processed after receiving the output of all its children processing. Uses the `run-series` library, that runs various async function in series, a common pattern also found at the famous `async` library.

by fiatjaf ~

HTML

<script src="http://wzrd.in/standalone/run-series@latest"></script>
<pre id="out"></pre>

JavaScript

function out(s) {
    document.getElementById('out').innerText += s + '\n';
}

/* tree visualization
root
    a
        b
            c
            d
        e
            f
    g
*/

// tree data
var c = { id:'c', children: []};
var d = { id:'d', children: []};
var g = { id:'g', children: []};
var f = { id:'f', children: []};
var e = { id:'e', children: [f]};
var b = { id:'b', children: [c,d]};
var a = { id:'a', children: [b,e]};
var m = { id:'m', children: [a,g]}; // the root

// the recursive function
function recurse(node, cb) {
    out(node.id + ', children: ' + node.children.map(function (x) { return x.id }).join(', '));
    var series = []
    for (var i=0; i<node.children.length; i++) {
        series.push((function (i) {
           return function (callback) {
               recurse(node.children[i], callback);
           }
        })(i))
    }
    runSeries(series, function (err, ids) {
        out('finished children of ' + node.id + ': ' + ids.join(', '))
        process(node, cb)
    })
}
function process(node, cb) {
    setTimeout(function () {
        out('\tprocessed ' + node.id)
        cb(null, node.id)
    }, 1000)
}

// kick off the recursion
function run() {
    recurse(m, function () {
      console.log('end')
    });
}
// and begin
run();