[英]NodeJS + MongoDB ASYNC results appearing late
我有一個簡單的函數,它返回通道中已連接用戶的列表,我在初始階段就使用了一個簡單的數組,但是知道,我想從mongodb數據庫中檢索一些用戶詳細信息並將其添加到該數組中。
我遇到的問題是,返回的結果為空,我稍后可以在控制台日志中清楚地看到這是因為查詢運行較晚,並且返回的結果是返回之前的結果。
我知道這是因為異步函數,我已經嘗試過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);
控制台日志結果
HERE THE ARRAY LOOKS EMPTY BEFORE SENDING BACK
[]
HERE THE ARRAY LOOKS EMPTY!
[]
HERE THE CONSOLE SHOWS ROOMUSERS FILLED IN
['user@user.com']
最終解決:好的,正如其中一位用戶評論的那樣,我正在考慮以同步模式進行操作,在解決了氣泡之后,我更改了send方法,以便在完成所有操作后進行發射。 請記住,我正在使用Q創建委托:)
//獲取指定房間的用戶功能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);
} );
}
我建議您使用Q Promises( https://npmjs.org/package/q )。 Promises是用於調度異步操作的非常強大的工具。
是的,這是在異步環境中使用同步樣式的問題。 在響應返回之前,執行先於io.sockets.clients( room )
運行。
以下應該工作:
io.sockets.clients(room).forEach(function (socket) {
// Your for-loop code
db.users.findOne( ... );
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.