将所有内容存储在Redis中并将其发送到模板

我正在构build一个小的Node.js应用程序,我需要做的一件事是获取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}); }); }; 

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

二:variables我不等于callback中的期望值,因为循环增加了,而且由于范围的限制,当第一次迭代的callback被调用(应该是0)时,i等于1。

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

考虑以下function:

 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}); } }); }); }); }; 

为了解决你的第一个问题,一旦收到所有结果,你需要在内部callback中调用最后的语句。 您可以通过计算预期的项目来确保这一点,并且只有在最后一个处理完毕后才调用渲染语句。

为了解决你的第二个问题,你可以使用forEach语句来引入另一个function范围。 在Javascript中,闭包的范围是在function层面定义的,而不是在块层面。 用forEachreplacefor循环是解决这个问题的一个很好的方法。

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

我最终build立在Didier的回应上,并使用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}); }); }); };