[英]NodeJS + MongoDB ASYNC results appearing late
I have a simple function which returns a list of connected users in a channel, I was using it in a initial stage with a simple array, but know, I want to retrieve some user details from the mongodb database and add it to that array. 我有一个简单的函数,它返回通道中已连接用户的列表,我在初始阶段就使用了一个简单的数组,但是知道,我想从mongodb数据库中检索一些用户详细信息并将其添加到该数组中。
The problem that I'm having is that the return is giving an empty result, I can clearly see later on in the console log that is because the queries are running late and the return is running before having the results back. 我遇到的问题是,返回的结果为空,我稍后可以在控制台日志中清楚地看到这是因为查询运行较晚,并且返回的结果是返回之前的结果。
I know it is because the asynchronous functions, I've tried with Q and others but I just simply cant get it working. 我知道这是因为异步函数,我已经尝试过Q和其他函数,但是我只是无法使其正常工作。 :(
:(
//GET USERS FOR SPECIFIED ROOM
function get_room_users( room ){
// create an array to hold all the usernames of the poeple in a specific room
var roomusers = new Array();
// get all the clients in ‘room1′
var clients = io.sockets.clients( room );
var i = 0;
for(var i = 0; i < clients.length; i++) {
db.users.findOne( { email: clients[i].username }, function(err, userdata) {
if( err || ! userdata ){
console.log('no user found');
} else {
console.log("DISPLAYING USER DATA: " + userdata.nickname);
roomusers[roomusers.length] = userdata.nickname;
console.log("HERE THE CONSOLE SHOWS ROOMUSERS FILLED IN");
console.log(roomusers);
i++;
}
});
}
console.log("HERE THE ARRAY LOOKS EMPTY BEFORE SENDING BACK");
console.log(roomusers);
return roomusers;
}
var users = get_room_users(room1);
console.log("HERE THE ARRAY LOOKS EMPTY!")
console.log(users);
CONSOLE LOG RESULT 控制台日志结果
HERE THE ARRAY LOOKS EMPTY BEFORE SENDING BACK
[]
HERE THE ARRAY LOOKS EMPTY!
[]
HERE THE CONSOLE SHOWS ROOMUSERS FILLED IN
['user@user.com']
FINALLY RESOLVED: Ok, so as one of the users commented I was thinking in a synchronous mode, I changed the emit method up after the bucle got resolved in order to emit when everything has been done. 最终解决:好的,正如其中一位用户评论的那样,我正在考虑以同步模式进行操作,在解决了气泡之后,我更改了send方法,以便在完成所有操作后进行发射。 Keep in mind that I'm using Q to create promisses :)
请记住,我正在使用Q创建委托:)
//GET USERS FOR SPECIFIED ROOM function get_room_users( room ){ //获取指定房间的用户功能get_room_users(room){
var the_promises = [];
// create an array to hold all the usernames of the poeple in a specific room
var roomusers = new Array();
// get all the clients in ‘room1′
var clients = io.sockets.clients( room );
clients.forEach(function (socket) {
var deferred = Q.defer();
db.usuarios.findOne( { email: socket.username }, function(err, userdata) {
if( err || ! userdata ){
console.log('no user found');
deferred.reject();
} else {
console.log("DISPLAYING USER DATA: " + socket.username);
roomusers[roomusers.length] = socket.username;
console.log("DENTRO DEL BUCLE");
console.log(roomusers);
deferred.resolve();
}
});
the_promises.push(deferred.promise);
});
Q.all(the_promises).done( function(){
console.log("ALL THINGS DONE!");
// broadcast to everyone in room 1 the usernames of the clients connected.
io.sockets.to( room ).emit('updateroomusers', roomusers);
} );
} }
I suggest you to use Q Promises ( https://npmjs.org/package/q ). 我建议您使用Q Promises( https://npmjs.org/package/q )。 Promises is a very powerfull tool for scheduling asynchronous operations.
Promises是用于调度异步操作的非常强大的工具。
Yes, this is a problem of using a synchronous style on an asynchronous environment. 是的,这是在异步环境中使用同步样式的问题。 Execution runs ahead of
io.sockets.clients( room )
before a response comes back. 在响应返回之前,执行先于
io.sockets.clients( room )
运行。
The following should work: 以下应该工作:
io.sockets.clients(room).forEach(function (socket) {
// Your for-loop code
db.users.findOne( ... );
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.