Understanding promises in node.js for recursive function

后端 未结 1 582
佛祖请我去吃肉
佛祖请我去吃肉 2020-12-11 04:47

I\'m trying to use recursive calls to get data out of redis, stopping and returning when the members return null.

So my data is added like this:

SADD         


        
1条回答
  •  被撕碎了的回忆
    2020-12-11 05:42

    • Try to be as pure as you can when working with promises. Avoid functions that have side effects, i.e. do manipulate any variables outside of their own scope.
    • Avoid passing callbacks to functions. Do only pass them to promise methods. You are doing this both with r_client.smembers() and when invoking your getFromRedis method

    I can see only one specific mistake that would keep your script from working:

    return [];
    

    does not have any effect from the callback. So, ret is never going to be resolved in this case. You would do ret.resolve([]); return; if at all. However, there are better solutions that let you use return again.

    To restructure your script, there are two points:

    • Use the Q.nfcall helper function (and the like) to avoid dealing with callback-style APIs directly. Use then to transform its result then - synchronously returning the tree leaves or a promise for the descendant-getting computations.
    • Use Q.all first, and then transform its result. Don't add a handler to each dependent, but get the whole result and build the construct in one single step.

    function getFromRedis(nodeName){
        return Q.ninvoke(r_client, "smembers", 'parents.' + nodeName).then(function(val) {
            // this is our returned object
            var constructedObject = {label: nodeName};
            if (val) {
                var dependents = val.map(function(par) {
                    // get a promise for the next level
                    return getFromRedis(nodeName+"."+par.toString());
                });
                return Q.all(dependents).then(function(dependentResults) {
                     constructedObject.parents = dependentResults;
                     return constructedObject;
                });
            } else { 
                return constructedObject; // without parents
            }
        });
    }
    
    getFromRedis( 'greg' ).done(function(out) {
        console.log('Final output: ' + JSON.stringify( out ));
    });
    

    0 讨论(0)
提交回复
热议问题