node.js - Returning a value from an asynchronous recursive function -
i have complex recursive function in node.js, sake of question simplified following:
function sum(tree) { if (!tree) return 0; var sumleft = sum(tree.left); var sumright = sum(tree.right); return sumleft + tree.val + sumright; } var exampletree = { val: 3, right: { val: 4 }, left: { val: 5, right: {val: 6}, left: {val: 7} } } console.log(sum(exampletree)); // returns 25 = 3+4+5+6+7
now want convert function "sum" asynchronous function:
function sumasync(tree, callback) { // ??? }
but, since function doesn't return value, don't know how values sumright , sumleft , combine them.
one possible option totally rewrite algorithm such iterative , not recursive (as suggested in question: how make synchronous recursive function asynchronous). but, in many cases might complicated , make entire program unreadable. there solution keeps simple structure of recursive function, while making asynchronous?
note: problem not sum values in tree... tree-sum function minimal working example.
edit: based on vkurchatkin's answer , comment, decided use async.parallel. result:
var async = require("async"); function sumasync (tree, callback) { if (!tree) return setimmediate(callback.bind(null, null, 0)); async.parallel([ sumasync.bind(this, tree.left), sumasync.bind(this, tree.right), ], function(err, results) { callback(err, tree.val+results[0]+results[1]); }); } sumasync(exampletree, function(err, result) { console.log(result); // prints 25 });
something might work:
function sumasync (tree, callback) { if (!tree) return setimmediate(callback.bind(null, null, 0)); var pending = 3; var sum = 0; var done = false; function handleerror (err) { if (!done) { callback(err); done = true; } } function _callback (err, res) { if (err) return handleerror(err); sum += res; if (!--pending && !done) { done = true; callback(null, sum); } } tree.fetchleft(function (err, left) { if (err) return handleerror(err); sumasync(left, _callback); }); tree.fetchright(function (err, right) { if (err) return handleerror(err); sumasync(right, _callback); }); tree.fetchvalue(_callback); }
it might complex, it's ad-hoc async.parallel
implementation, can use instead.
Comments
Post a Comment