Как я могу ждать асинхронных событий в JavaScript?
-
20-12-2019 - |
Вопрос
Я новичок в JavaScript, и все еще не знаком с асинхронными функциями ...
Я работаю с Node.js, чтобы создать чат-сервер, это часть моего кода, который прослушивает событие getListConnected
, и когда он запускал его искать все подключенные генеракодицетагкод в заданном пространстве имен, а затем для каждого клиента IХраните его «имя пользователя» на другой массив, преобразуйте его в ответ JSON, а затем отправьте:
socket.on('getListConnected', function(msg){
var clients = namespace.clients();//get all client in that nsp
var usernames = Array() ;//init array
for(i in clients)//for each clients
{
clients[i].get("username", function(value){
usernames.push(value);
});
}
socket.emit('getListConnected',JSON.stringify(usernames));//send
});
.
Проблема с этим кодом является метод Client.get () - это асинхронная ведьма означает, что имена пользователей отправляются пустыми.
Как я могу ждать имена пользователей, пока он не заполнен, или как я могу ждать петли, пока не закончится?
Решение
Вы могли бы использовать промежуточное программное обеспечение для обещаний, что-то вроде Bluebird или выможет держать счетчик, чтобы проверить, были ли все имена пользователей, что-то вроде
socket.on('getListConnected', function (msg) {
var clients = namespace.clients();
var usernames = [];
var counter1 = 0;
var counter2 = 0;
for (i in clients) {
counter1++; // number of clients
clients[i].get("username", function (value) {
usernames.push(value);
counter2++; // number of clients added to array
if (counter1 === counter2) {
socket.emit('getListConnected', JSON.stringify(usernames));
}
});
}
});
. Другие советы
Вот пример Bluebird, настроен для вашей ситуации: [Это заимствовало сильно от Пример Виктора Куинна ]
Используя одно и то же определение обещания, которое использовал Victor:
var Promise = require('bluebird');
var promiseWhile = function(condition, action) {
var resolver = Promise.defer();
var loop = function() {
if (!condition()) return resolver.resolve();
return Promise.cast(action())
.then(loop)
.catch(resolver.reject);
};
process.nextTick(loop);
return resolver.promise;
};
.
Суммировано с вашим пользователем вызовом:
var i = 0;
promiseWhile(function() {
return i < clients.length;
}, function(value) {
return new Promise(function(resolve, reject) {
clients[i].get("username", function(value){
usernames.push(value);
});
i++;
resolve();
});
}).then(function() {
console.log("usernames are: " + usernames);
});
.