チャネルに接続されているユーザーのリストを返す単純な関数があります。単純な配列を使用して初期段階で使用していましたが、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']
最終的に解決: ユーザーの 1 人が、私は同期モードで考えていたとコメントしたので、bucle が解決された後に、すべてが完了したときに発行するために、発行メソッドを変更しました。Q を使用してプロミスを作成していることを覚えておいてください :)
//指定された部屋のユーザーを取得 function 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);
} );
}