Node.js/ 使 redis 调用异步
Posted
技术标签:
【中文标题】Node.js/ 使 redis 调用异步【英文标题】:Node.js/ Make redis call async 【发布时间】:2015-12-01 09:53:34 【问题描述】:我在node.js中使用redis客户端
var db = require("redis");
var dbclient = db.createClient();
我用下一种方式加载数据库:
dbclient.zrange("cache", -1000000000000000, +1000000000000000, function(err, replies)
logger.info("Go to cache");
for (var i=0; i < replies.length; i++)
(function(i)
// Do some commands with the result
)(i)
)
我注意到我的应用程序从哪里开始,需要 30~ 秒。用于执行数据库查询。此时,不会处理来自Express
模块的其他请求。
我该如何解决这个问题?为什么没有异步?
【问题讨论】:
redis的异步API。但是loop for
- 没有。
什么是"do some commands with the result"? replies.length
是什么?
【参考方案1】:
正如 stdob 所说,您的代码中唯一不是异步的部分是 for
循环部分。就个人而言,我会创建一个child process 并运行数据库查询以及您决定对输出执行的任何操作。如果这对您的应用程序不起作用,您可能只需要延迟启动程序这 30 秒或以不同的方式处理缓存。
【讨论】:
【参考方案2】:如果您担心正常运行时间,那么您应该使用ZSCAN
使用 COUNT 选项在每次通话中获取更多数据,但请记住:
虽然 SCAN 不保证每次迭代返回的元素数量,但可以使用 COUNT 选项凭经验调整 SCAN 的行为
并且在每个结果中使用setImmediate 函数迭代到下一个 SCAN。
var cursor = '0';
function doscan()
dbclient.zscan("cache", cursor, "COUNT", "100", function(err, replies)
logger.info("Go to cache");
// Update the cursor position for the next scan
cursor = res[0];
if (cursor === '0')
return console.log('Iteration complete');
else
for (var i=0; i < replies.length; i++)
(function(i)
// Do some commands with the result
)(i)
setImmediate(function() doscan() );
)
【讨论】:
【参考方案3】:您可以为此使用 Iced-CoffeeScript,例如 https://github.com/Terebinth/britvic/blob/master/server/models/hive_iced.iced#L101
【讨论】:
以上是关于Node.js/ 使 redis 调用异步的主要内容,如果未能解决你的问题,请参考以下文章
node.js 可以编写一个方法,以便可以两种方式调用它 - 即使用回调或异步/等待?