Currently, using dig() incompatible:
// asynchronous with callback dig(52, treeArray, function (t) { res.json(t); }); // then synchronous with `return`? treeArray.concat(dig(rows[i].tree_id, treeArray));
In addition, concat in the last line actually does little, since it does not change the array to which it called. You probably wouldn’t want this, since dig was passing around treeArray , and not defining a new treeSet , as in getBranches . So, if that were the case, then every time I would add a treeArray to the end.
You can still use concat with multiple treeSet s, but you need to keep its return value:
treeSet = treeSet.concat(subSet);
And you will have to replace the for loop with an asynchronous iterator, since the loop will not wait for asynchronous operations before continuing. There are several options for this in the async library if you want to try it.
So with a few treeSet s, concat and async.forEachSeries you can try:
function dig(tree_id, callback) { var treeSet = []; hasLines(tree_id, function (yep) { if (yep) { treeSet.push(tree_id); } pool.query('SELECT * from tree where parent_id = ?', [tree_id], function (err, rows) { function each(row, next) { dig(row.tree_id, function (subSet) { treeSet = treeSet.concat(subSet); next(null); }); } function done() { callback(treeSet); } async.forEachSeries(rows, each, done); }); }); } dig(52, function (treeSet) { res.json(treeSet); });