也许结果并不奇怪,但我在1-2个月前开始使用Node,所以对我来说他们是......
我有一个循环,用于排除hgetall
(Redis命令)返回的数组的每个其他值,在该循环中,我调用一个函数从另一个表中获取所有值,并将键存储在已排序的数组中。这比我想象的更难解释。这是我的代码:
Pastebin:http://pastebin.com/tAVhSUV1(或见下文)
function getInfo (cn, callback) {
var anArray = [];
redis_client.hgetall('chat_info:' + cn, function (err, vals) {
if(err) { throw err; }
for(i in vals) {
anArray.push(vals[i]);
}
return callback(anArray);
});
}
redis_client.hgetall('chat_rooms:' + POST.chat_name, function (err, val) {
if(err) { throw err; }
var vars = [],
rArr = [];
for (i in val) {
vars.push(i);
}
for(var i = 0; i < vars.length; i += 1) {
if(i%2 === 0) {
getInfo(vars[i], function (hej) {
rArr.push(hej);
});
}
}
});
在整个循环之后执行从getInfo()
调用的回调。我错过了什么吗?因为它不能那样做,对吧? (当我使用rArr(在循环之后)它是空的,nbBut如果我在回调中记录它,那么在循环之后之后所有其他内容都会被记录)
答案 0 :(得分:0)
是的,这可能是正常的。
了解在hgetall
调用后执行回调。这意味着当redis函数接收到某些内容时,它将调用回调函数。换句话说,所有回调都可以在以后执行。
由于javascript只能在一个线程中运行,因此对hgetall
的调用应该是阻塞,因为它们来自for循环。但是你肯定使用异步IO。 for循环结束然后它将开始调用在javascript事件循环内排队的每个回调。
修改强>
不幸的是,要实现您要做的事情,您应该将代码包装在许多其他回调中。您可以使用此项目来简化:https://github.com/caolan/async
您应该可以使用npm install async
安装它。
你必须做那样的事情:
function getInfo (cn) {
return function(callback) {
var anArray = [];
redis_client.hgetall('chat_info:' + cn, function (err, vals) {
if(err) { throw err; }
for(i in vals) {
anArray.push(vals[i]);
}
return callback(anArray);
});
};
}
redis_client.hgetall('chat_rooms:' + POST.chat_name, function (err, val) {
if(err) { throw err; }
var vars = [],
rArr = [],
callbacks = [];
for (i in val) {
vars.push(i);
}
for(var i = 0; i < vars.length; i += 1) {
if(i%2 === 0) {
callbacks.push(getInfo(vars[i]));
}
}
async.series(callbacks, function (err, results) {
// Final code here
});
});