在我的应用程序中,我有以下内容:
client.on('test', function(req, fn) {
var returnArr = [];
redis.hkeys(req, function (err, replies) {
replies.forEach(function(reply, i) {
if (reply.indexOf('list.') > -1) {
redis.hgetall(reply.substring(5), function(err, r) {
returnArr.push({name:r['name'],index:i});
console.log(returnArr);
});
}
});
console.log(returnArr);
});
console.log(returnArr);
});
出于某种原因,第二个和第三个日志包含一个空白数组,即使该数组在事件开始时声明过一次。有什么想法吗?
编辑:抱歉,我在这里发布时不假思索地更改了变量名。当它被命名为任何东西时,就会发生这种情况。
最佳答案
那些 redis 调用是异步的。这就是您为他们提供回调的原因。即使您出于这个原因修复了变量名称,代码也不会工作。
详细说明:“hkeys”回调中的代码将在数据可用时调用。但是,该调用将立即返回,因此此时您的数组中将没有任何内容。
您不能将异步调用包装在一个函数中并期望返回一个值。它根本行不通。
相反,一般模式是完全按照 redis API(以及 node.js 世界中的几乎所有其他东西;事实上,这就是重点):给你自己的函数一个回调参数,当合适的。在您的情况下,它将位于最后一个被调用的“hgetall”回调中。它应该确定您的结果数组中的值与键的数量一样多,因此是时候调用传递给您的函数的回调了。
(我应该指出,鉴于整个函数似乎是对某事的回调,因此不清楚您要做什么。)
另一种方法是使用某种“ promise ”模式,尽管这实际上只是同一想法的重组。
编辑 — 带有回调的 API 的一般模式如下所示:
function yourAPI( param1, param2, callback ) {
// ...
some.asynchronousFunction( whatever, function( result ) {
callback( result );
}
}
现在,在您的情况下,您正在发出多个 异步服务请求,并且您需要确定何时该调用回调。我认为您可能希望遍历调用中的“回复”以获取 key 并提取要获取的 key 列表:
redis.hkeys(req, function (err, replies) {
var keys = [];
replies.forEach(function(reply, i) {
if (reply.indexOf('list.') > -1) {
keys.push( reply.substring(5) );
}
});
keys.forEach( function( key ) {
redis.hgetall(key, function(err, r) {
returnArr.push({name:r['name'],index:i});
if (returnArr.length === keys.length) {
// all values ready
callback( returnArr );
}
});
});
关于javascript - node.js/socket.io 消失变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9790559/