3

我正在尝试从 redis 实例中获取一堆密钥。我正在使用节点redis。我正在使用一个循环:

for( var i=1; i<=num; ++i ){
    client.get(key + ':' + num, function (err, reply) {
        obj[num] = reply;
    });
}
return obj;

obj只是未定义。我觉得我可能有问题,因为get显然是异步调用的。还有另一种方法可以实现这一目标吗?我应该将值存储在排序集中吗?

4

1 回答 1

10

我将根据编码界面和您client.get()的异步评论进行猜测。这意味着它会“稍后”调用传递给它的回调函数,而不是立即调用。因此,您不能使用同步编码模式来收集来自多次调用client.get()的结果,因为obj当您的函数返回时,结果尚不可用。因此obj尚未填充结果。

如果您想知道多个异步调用何时完成,那么您必须以非常不同的方式编写代码。而且,结果仅在回调函数中可用,而不是在函数末尾。

总之,我发现您的代码存在多个问题:

  1. client.get()是异步的,所以当你的函数返回时它还没有完成
  2. 您可能应该使用i, 而不是num在您的client.get()通话中,以便每次通过for循环都会生成不同的请求。
  3. 循环中的值i必须在闭包中冻结,以便保留它的值,以便在稍后调用的回调函数中使用。
  4. 如果obj实际上是未定义的,那可能是因为您没有将其初始化为空对象。

这是一种方法:

var obj = {};
var remaining = num;
for( var i=1; i<=num; ++i ){
    // create a closure here to freeze the value of i in the callback
    (function(i) {
        client.get(key + ':' + i, function (err, reply) {
            obj[i] = reply;
            // see if all asynch calls are done yet
            --remaining;
            if (remaining === 0) {
                // all asynch calls to client.get() are done now
                // in here, you can use the obj object and the results put on it
            }
        });
    })(i);
}
于 2013-05-20T04:06:21.543 回答