我是Node的新手,并试图确保我对JSON驱动的Web应用程序使用了合理的设计。
我已经在Redis中存储了一堆数据,并且正在通过node检索它们,并将结果从Redis中流出来。这是我正在做的一个很好的例子:
app.get("/facility", function(req, res) { rc.keys("FACILITY*", function(err, replies) { res.write("["); replies.forEach(function (reply, i) { rc.get(reply, function(err, reply) { res.write(reply); if (i == replies.length-1) { res.write("]"); res.end(); } else res.write(","); }); }); }); });
本质上,我是从Redis获取一组密钥,然后请求每个密钥,然后将结果流式传输到半手动创建的JSON(来自Redis的字符串已经在JSON中)。现在,这很好用,但是我不禁会以为i == replies.length-1有点不整洁?
我可以在Redis中使用mget来完成所有这一切,但这并不是我想要得到的重点。这是处理forEach异步循环,流式传输输出并优雅地用res.end关闭连接的最佳方法。
这是最好的方法,还是我可以遵循的更优雅的模式?
上面的代码可能无法满足您的期望。您将按.get()顺序开始每一个,但它们可能不会按顺序回叫- 因此结果可以按任何顺序输出。如果要流式传输结果而不是将其收集到内存中,则需要.get()按顺序进行。
.get()
我认为caolan的异步库使此操作变得更加容易。您可以使用以下一种方法来按顺序获取每个项目(警告,未经测试):
app.get("/facility", function(req, res) { rc.keys("FACILITY*", function(err, replies) { var i = 0; res.write("["); async.forEachSeries(replies, function(reply, callback){ rc.get(reply, function(err, reply) { if (err){ callback(err); return; } res.write(reply); if (i < replies.length) { res.write(","); } i++; callback(); }); }, function(err){ if (err) { // Handle an error } else { res.end(']'); } }); }); });
如果您不关心订单,请async.forEach()改用。
async.forEach()
如果您不介意收集结果并希望它们按顺序返回,则可以这样使用async.map()(警告,也未经测试):
async.map()
app.get("/facility", function(req, res) { rc.keys("FACILITY*", function(err, replies) { async.map(replies, rc.get.bind(rc), function(err, replies){ if (err) { // Handle an error } else { res.end('[' + replies.join(',') + ']'); } }); }); });