发布:2023/11/2 23:14:56作者:管理员 来源:本站 浏览次数:532
希望有人可以协助解决有关 node-redis 的(简单)异步问题。我正在尝试从 redis 数据库中的哈希加载一个集合,然后进一步使用该填充的集合。这是代码片段:-
[点击复制代码] Java
var redis_client = redis.createClient(REDIS_PORT, REDIS_URL);
redis_client.hgetall(target_hash,function(e,o){
Object.keys(o).forEach(function(target){
// get the "name" from the hash
redis_client.hget(o[target],"name",function(e,o){
if (e){
console.log("Error occurred getting key: " + e);
}
else {
redis_client.sadd("newset",o);
}
});
});
// the following line prints nothing - why ??
redis_client.smembers("newset",redis.print);
当我检查 redis 中“newset”的内容时,它按预期填充,但在运行时它显示为空。我确定这是一个异步问题 - 非常感谢任何帮助!
请您参考如下方法:
hgetall是一个异步调用:当它收到redis服务器的回复时,它最终会调用你的回调function(target){ ... }。但在您的脚本中,它实际上会立即返回。由于 hgetall 返回速度非常快,Node 将立即运行下一条语句 smembers。但是此时 sadd 语句还没有运行(即使你的系统非常快,因为还没有上下文切换)。
您需要做的是确保在执行所有可能的 sadd 调用之前,不会调用 smembers。 redis_client 提供了 multi 函数,允许您将所有 sadd 调用排队,并在它们全部完成时运行回调。我没有测试过这段代码,但你可以试试这个:
[点击复制代码] Java
var redis_client = redis.createClient(REDIS_PORT, REDIS_URL);
redis_client.hgetall(target_hash, function(e, o) {
var multi = redis_client.multi();
var keys = Object.keys(o);
var i = 0;
keys.forEach(function (target) {
// get the "name" from the hash
redis_client.hget(o[target], "name", function(e, o) {
i++;
if (e) {
console.log("Error occurred getting key: " + e);
} else {
multi.sadd("newset", o);
}
if (i == keys.length) {
multi.exec(function (err, replies) {
console.log("MULTI got " + replies.length + "replies");
redis_client.smembers("newset", redis.print);
});
}
});
});
});
一些库有一个内置的 forEach 等价物,它允许你指定一个函数,当循环完成时调用。如果没有,您必须手动跟踪有多少次回调,并在最后一次回调之后调用 smembers。
© Copyright 2014 - 2024 柏港建站平台 ejk5.com. 渝ICP备16000791号-4