簡體   English   中英

理解node.js中的promises for recursive function

[英]Understanding promises in node.js for recursive function

我正在嘗試使用遞歸調用從redis中獲取數據,在成員返回null時停止並返回。

所以我的數據添加如下:

SADD parents.<name> <parent1> <parent2>
SADD parents.<parent1> <grandparent1> <grandparent2>
...

最終數據應如下所示:

[
 {
     label: <name>,
     parents: [
         { label: <parent1>,
           parents: [ {label: <grandparent1>}, {label: <grandparent2> }] },
         { label: <parent2> }
     ]
 }
]

這是我正在搞亂的代碼(有點從不同的來源拼湊而成),但我不知道我在做什么。 不確定這段代碼是否有用,我可能會偏離軌道。

var redis = require('node-redis');
var r_client = redis.createClient();
var Q = require('q');


function getFromRedis(nodeName){
        var ret = Q.defer();
        r_client.smembers('parents.' + nodeName,function(err,val){
                if (err) ret.reject(err);
                else {
                        var constructedObject={};  //this is our returned object
                        var dependents=[];
                        if (val)
                        {
                                for (var k in val){  //iterate the keys in val
                                        constructedObject.name = val[k];

                                        dependents.push(getFromRedis(val[k])
                                        .then(function(subVal){
                                                constructedObject[k]=subVal;
                                                return ret.promise;
                                        })
                                        );
                                }
                        }
                        else { return [] }

                }
                Q.all(dependents)
                .then(function(){ret.resolve(constructedObject);},ret.reject.bind(ret));

        });
                return ret;
}

getFromRedis( 'greg', function(out) {console.log('Final output: ' + JSON.stringify( out ))} );

我可以看看這些例子,從理論上看它應該如何工作,但是我無法理解它應該如何與q實現一起工作。 任何幫助將不勝感激。

  • 在使用promises時盡量保持純潔。 避免使用具有副作用的函數,即操作超出其自身范圍的任何變量。
  • 避免將回調傳遞給函數。 只傳遞給promise方法。 您正在使用r_client.smembers()和調用getFromRedis方法執行此操作

我只能看到一個會阻止你的腳本工作的特定錯誤:

return [];

回調沒有任何影響。 因此,在這種情況下, ret永遠不會得到解決。 你會做ret.resolve([]); return; ret.resolve([]); return; 如果有的話。 但是,有更好的解決方案可以讓您再次使用return

要重構腳本,有兩點:

  • 使用Q.nfcall輔助函數 (等)可以避免直接處理回調式API。 then使用then轉換其結果 - 同步返回樹葉或后代獲取計算的承諾。
  • 首先使用Q.all ,然后轉換其結果。 不要為每個dependent項添加處理程序,而是獲取整個結果並在一個步驟中構建construct

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 ));
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM