2013-05-30 22 views
1

我正在构建一个Node.js应用程序,我需要做的一件事是获取Redis数据存储区中的所有数据,并将其显示在此特定页。到目前为止,我的代码如下所示:获取存储在Redis中的所有内容并将其发送到模板

exports.view = function (req, res) { 
    rclient.keys('*', function (err, reply) { 
     var data = {}; 

     // Get the value for each key 
     for (var i = 0; i < reply.length; i++) { 
      rclient.GET(reply[i], function (err, value) { 
       data[reply[i]] = value; 
      }); 
     } 

     res.render('view', {title: 'Datastore', data: data}); 
    }); 
}; 

我在这里至少有两个问题。一:由于Node.js的异步特性,当我将它传递给我的渲染函数时,数据变量是空的。避免这种情况的正确方法是什么?

二:变量我不等于我的回调中的期望值,因为循环增加了,并且由于范围的限制,在第一次迭代的回调被调用时,我等于1(它应该是0)。

我对Node.js很陌生,所以我确定我做错了什么。

回答

1

考虑以下功能:

exports.view = function (req, res) { 
    rclient.keys('*', function (err, reply) { 
    var data = {}; 
    var count = reply.length; 
    reply.forEach(function(key) { 
     rclient.get(key, function (err, value) { 
     data[key] = value; 
     --count; 
     if (count <= 0) { 
      res.render('view', {title: 'Datastore', data: data}); 
     } 
     }); 
    }); 
    }); 
}; 

解决您的第一个问题,你需要一旦所有的结果已经接收到呼叫的最终声明在内的回调。您可以通过计算预期的项目来确保这一点,并且只有在最后一个处理完成后才调用渲染语句。

要解决您的第二个问题,您可以使用forEach语句,它引入了另一个功能范围。在Javascript中,闭包的范围是在功能层面定义的,而不是在块层面。通过forEach替换for循环是处理这个问题的一种优雅方式。

最后一点:在真实应用程序中使用KEYS命令是非常糟糕的做法。 KEYS只能用作调试工具。

+0

这整个应用程序,就是要调试工具只:) –

0

我结束了建立在德罗巴的反应,并利用async.js

exports.view = function (req, res) { 
    // Get all of the key information for the given key 
    var getKeyInfo = function (key, callback) { 
     async.parallel([ 
      rclient.GET.bind(rclient, [key]), 
      rclient.TTL.bind(rclient, [key]), 
      rclient.TYPE.bind(rclient, [key]) 
     ], callback); 
    } 

    // Fetch all keys in our data store 
    rclient.KEYS('*', function (err, keys) { 
     var asyncCallbacks = {}; 

     // Build an array of callbacks for our async operation 
     for (var i = 0; i < keys.length; i++) { 
      asyncCallbacks[keys[i]] = async.apply(getKeyInfo, keys[i]); 
     } 

     // Asynchronously get the data for each key in the data store 
     async.parallel(asyncCallbacks, function (err, results) { 
      res.render('view', {title: 'Datastore', data: results}); 
     }); 
    }); 
}; 
相关问题