【问题标题】:Redis node.js - chaining calls to get user dataRedis node.js - 链接调用以获取用户数据
【发布时间】:2013-04-07 19:05:56
【问题描述】:

我有一个用户数据库:个人资料、产品、配置和其他用户可以拥有的东西。我正在尝试找到一种方法来成功链接我的 redis 调用(一个“getAll”函数),以便我可以返回一个包含所有这些东西的对象,例如:

user = {
    profile: {},
    products: {},
    config: {},
    ...
}

这是我访问它们的方式/我正在尝试做的事情:

User.getAll = function(uid, next){

    var user = {};
    var multi = client.multi();

    var key = 'user' + uid;
    client.hgetall(key, function(err, profile){
        user.profile = profile;
        //signal that profile is ready
    }

    key = 'products:' + uid;
    client.smembers(key, function(err, arr){
        key = key + ':';
        for (i=0; i < arr.length; i++){
            multi.hgetall(key + arr[i]);
        }
        multi.exec(function(err, products){
            user.products = products;
            //signal that products is ready
        }));
    })

    if (ready) { //obviously this isn't correct.
      return next(null, user);
    }
}

收到所需的所有数据后,如何恢复?事件发射器是正确的方法吗?

【问题讨论】:

    标签: node.js events redis publish-subscribe


    【解决方案1】:

    我认为事件发射器在这里不是一个好的选择。您可以像这样跟踪所有呼叫:

    User.getAll = function(uid, next){
        var requests = ["first", "second"];
        var check_request = function(_key) {
            var idx = requests.indexOf(_key);
            if (idx!==-1) {
                requests.splice(idx, 1);
            }
            if (!requests.length) {
                next(user);
            }
        };
    
        // ORIGINAL CODE + check_request
        var user = {};
        var multi = client.multi();
    
        var key = 'user' + uid;
        client.hgetall(key, function(err, profile){
            user.profile = profile;
            check_request("first");
        }
    
        key = 'products:' + uid;
        client.smembers(key, function(err, arr){
            key = key + ':';
            for (i=0; i < arr.length; i++){
                multi.hgetall(key + arr[i])
            }
            multi.exec(function(err, products){
                user.products = products;
                check_request("second");
            }));
        })
    }
    

    显然你会使用比requests = ["first", "second"]; 更有意义的东西,但我希望你能明白。

    还可以查看async.js。这是一个很好的库,它为您简化了它,它可以做更多的事情。

    【讨论】:

    • 很好,将为此尝试 async.parallel。
    【解决方案2】:

    我认为你应该检查async 模块。 parallel的流量控制功能将非常适合您:

    User.getAll = function(uid, next){
    
        var user = {};
        var multi = client.multi();
    
        async.parallel([
            function(callback){
                // first task
                var key = 'user' + uid;
                client.hgetall(key, callback);
            },
            function(callback){
                // second task
                var key = 'products:' + uid;
                client.smembers(key, function(err, arr){
                    if (err) return callback(err); // error check!!!
                    key = key + ':';
                    for (i=0; i < arr.length; i++){
                        multi.hgetall(key + arr[i]);
                    }
                    multi.exec(callback);
                })
            }
        ], function(err,res){
            // async callback
            if (err) return next(err); // error check!!!
            user.profile = res[0];
            user.products = res[1];
            return next(null, user);
        })
    }
    

    【讨论】:

      猜你喜欢
      • 2023-03-21
      • 2021-03-17
      • 2017-06-14
      • 2020-04-09
      • 2022-08-15
      • 2016-06-19
      • 1970-01-01
      • 2014-02-17
      • 1970-01-01
      相关资源
      最近更新 更多