Вопрос

Я новичок в 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);
});
.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top