Frage

Ich bin neu in JavaScript und mit asynchronen Funktionen noch nicht vertraut ...

Ich arbeite mit node.js, um einen Chat-Server zu erstellen. Dies ist ein Teil meines Codes, der abgehört wird getListConnected Ereignis und wenn es ausgelöst wurde, suchen Sie nach allen verbundenen clients in einem bestimmten Namespace, und dann speichere ich für jeden Client seinen „Benutzernamen“ in einem anderen Array, konvertiere ihn in eine JSON-Antwort und sende dann:

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

Das Problem mit diesem Code besteht darin, dass die Methode client.get() asynchron ist, was bedeutet, dass Benutzernamen leer gesendet werden.

Wie kann ich auf Benutzernamen warten, bis sie gefüllt ist, oder wie kann ich auf die Schleife warten, bis sie fertig ist?

War es hilfreich?

Lösung

Sie könnten Middleware für Versprechen verwenden, so etwas wie Bluebird, oder Sie könnten einen Zähler führen, um zu überprüfen, ob alle Benutzernamen abgerufen wurden, so etwas wie

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

        });
    }

});

Andere Tipps

Hier ist ein Bluebird-Beispiel, angepasst an Ihre Situation:[es lehnt sich stark an Victor Quinns Beispiel]

Unter Verwendung derselben Promise-Definition, die Victor verwendet hat:

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

Mit Ihrem benutzerdefinierten Aufruf instanziiert:

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);
});
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top