Question

Je suis nouveau sur JavaScript et je ne suis toujours pas familier avec les fonctions asynchrones...

Je travaille avec node.js pour créer un serveur de chat, c'est une partie de mon code qui est écoutée getListConnected événement et quand il s'est déclenché, il recherche tous les connectés clients dans un espace de noms donné, puis pour chaque client, je stocke son « nom d'utilisateur » dans un autre tableau, je le convertis en réponse json, puis j'envoie :

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
                    });

Le problème avec ce code est que la méthode client.get() est asynchrone, ce qui signifie que les noms d'utilisateur sont envoyés vides.

Comment puis-je attendre les noms d'utilisateur jusqu'à ce qu'ils soient remplis, ou comment puis-je attendre la boucle jusqu'à ce qu'elle soit terminée ?

Était-ce utile?

La solution

Vous pouvez utiliser un middleware pour les promesses, quelque chose comme Oiseau bleu, ou vous pouvez conserver un compteur pour vérifier si tous les noms d'utilisateur ont été obtenus, quelque chose comme

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));
            }

        });
    }

});

Autres conseils

Voici un exemple Bluebird, personnalisé pour votre situation :[il emprunte beaucoup à L'exemple de Victor Quinn]

En utilisant la même définition de promesse que celle utilisée par 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;
};

Instancié avec votre appel personnalisé :

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);
});
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top