2013-05-30 26 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}); 
     }); 
    }); 
}; 
相關問題