NodeJS + MongoDB ASYNC结果出现较晚

我有一个简单的函数,它返回一个通道中的连接用户列表,我在初始阶段用一个简单的数组来使用它,但是知道,我想从mongodb数据库中检索一些用户细节,并将其添加到该数组中。

我遇到的问题是返回给出了一个空的结果,我可以在控制台日志中清楚地看到,这是因为查询运行较晚,并且在返回结果之前运行返回。

我知道这是因为asynchronousfunction,我已经尝试与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日志结果

 HERE THE ARRAY LOOKS EMPTY BEFORE SENDING BACK [] HERE THE ARRAY LOOKS EMPTY! [] HERE THE CONSOLE SHOWS ROOMUSERS FILLED IN ['user@user.com'] 

最后解决:好吧,所以当一个用户评论我是在同步模式下思考的时候,我在bucle解决后改变了emit方法,以便在所有事情都完成时发出。 请记住,我正在使用Q创造promisses 🙂

//获取指定房间的用户函数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); } ); 

}

我build议你使用Q Promises( https://npmjs.org/package/q )。 承诺是一个非常强大的调度asynchronous操作的工具。

是的,这是在asynchronous环境中使用同步样式的问题。 在响应返回之前,执行在io.sockets.clients( room )之前运行。

以下应该工作:

 io.sockets.clients(room).forEach(function (socket) { // Your for-loop code db.users.findOne( ... ); });