Search code examples
javascriptnode.jssocket.iodom-eventsevent-driven

How can I wait for asynchronous events in Javascript?


I'm new to JavaScript, and still not familiar with asynchronous functions...

I'm working with node.js to create a chat server, this is a part of my code that's listen to getListConnected event and when it triggered it look for all connected clients in a given namespace, and then for each client I store their 'username' to another array, convert it to JSON response and then send:

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

The problem with this code is the client.get() method is asynchronous which means that usernames are sent empty.

How can I wait for usernames until it's filled, or how can I wait for the loop until it's finished?


Solution

  • You could use middleware for promises, something like Bluebird, or you could keep a counter to check if all usernames have been gotten, something like

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