0

也许结果并不奇怪,但我在 1-2 个月前开始使用 Node,所以对我来说它们是......

我有一个循环,它对(Redis 命令)返回的数组的所有其他值进行排序hgetall,在该循环中,我调用一个函数从另一个表中获取所有值,其中键存储在排序后的数组中。这比我想象的更难解释。这是我的代码:

Pastebin:http://pastebin.com/tAVhSUV1(或见下文)

function getInfo (cn, callback) {
        var anArray = [];
        redis_client.hgetall('chat_info:' + cn, function (err, vals) {
                if(err) { throw err; }
                for(i in vals) {
                        anArray.push(vals[i]);
                }
                return callback(anArray);
        });
}

redis_client.hgetall('chat_rooms:' + POST.chat_name, function (err, val) {
        if(err) { throw err; }
        var     vars = [],
                rArr = [];

        for (i in val) {
                vars.push(i);
        }
        for(var i = 0; i < vars.length; i += 1) {
                if(i%2 === 0) {
                        getInfo(vars[i], function (hej) {
                                rArr.push(hej);
                        });
                }
        }      
});

来自调用的回调getInfo()在整个循环之后执行。我在这里错过了什么吗?因为它做不到,对吧?(当我使用 rArr (在循环之后)它是空的,nb但是如果我将它记录在回调中,它会在循环之后写入的所有其他内容之后被记录)

4

1 回答 1

0

是的,这可能是正常的。

了解回调是在hgetall调用之后执行的。这意味着当 redis 函数收到一些消息时,它将调用回调。换句话说,所有回调都可以稍后执行。

由于 javascript 仅在一个线程中工作,因此hgetall当它们进入 for 循环时,对的调用应该被阻塞以执行。但是因为您更肯定使用异步 IO。for 循环结束,然后它将开始调用在 javascript 事件循环中排队的每个回调。

编辑

不幸的是,要实现您想要做的事情,您应该将代码包装在许多其他回调中。您可以使用此项目使其更容易:https ://github.com/caolan/async

您应该能够使用npm install async.

你必须做这样的事情:

function getInfo (cn) {
        return function(callback) {
            var anArray = [];
            redis_client.hgetall('chat_info:' + cn, function (err, vals) {
                if(err) { throw err; }
                for(i in vals) {
                        anArray.push(vals[i]);
                }
                return callback(anArray);
            });
        };
}

redis_client.hgetall('chat_rooms:' + POST.chat_name, function (err, val) {
        if(err) { throw err; }
        var     vars = [],
                rArr = [],
                callbacks = [];

        for (i in val) {
                vars.push(i);
        }

        for(var i = 0; i < vars.length; i += 1) {
                if(i%2 === 0) {
                        callbacks.push(getInfo(vars[i]));
                }
        }

        async.series(callbacks, function (err, results) {
           // Final code here
        });
});
于 2013-12-14T16:06:15.023 回答