0

我有一个用户数据库:个人资料、产品、配置和其他用户可以拥有的东西。我正在尝试找到一种方法来成功链接我的 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);
    }
}

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

4

2 回答 2

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。这是一个很好的库,它为你简化了它,它可以做更多的事情。

于 2013-04-07T19:15:19.957 回答
1

我认为你应该检查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);
    })
}
于 2013-04-07T19:50:06.847 回答