0

Right now in my nodejs socket.io 'game' I would like to cycle through all users currently online*, each having their opportunity to be a leader and click a button that would sequentially make the next user the leader (to, again, click a button that makes the next user the leader. You get the idea). My issue is that when I make the while loop wait for the 'leader' socket to trigger the leaderSelection event to increment the while loop, the while loop instead creates an infinite loop, crashing my browser. Simply put, how can I make a while loop wait (a theoretically infinite amount of time) until it gets incremented, instead of running infinitely. Hopefully this was clear enough. Here's my code:

while(i < ids.length) { //Go through all ids one by one
        //Select current id and make that person the leader
        socket.broadcast.to(ids[i]).emit('leader', { message: 'You are the leader for this round', options: 'THIS WOULD BE A SELECTION BUTTON FOR THE leaderSelection EVENT LISTENER'});
        //Loop through all the other people that are not the leader and say they are the users for this round
        for(var e = 0; e < ids.length; e++) {
            if(i == e) { //Skip current leader
                console.log('skipped ' + usernames[i]); 
                continue;
            } 
            socket.broadcast.to(ids[e]).emit('user', { message: 'You are a user for this round'});
        }
        //When the leader socket clicks the 'select' button, the while loop will go to the next person to be a leader
        socket.on('leaderSelection', function(data) {
            i++; //Here is the issue, the while loop crashes my browser trying to wait for the increment. 
        });
    }
3
  • You cannot do that. Commented Jul 5, 2017 at 23:42
  • Fundamentally, the problem is you're deadlocked. Browser Javascript is single threaded. While your while loop is going, nothing else can occur, not even that leaderSelection callback. So your loop can't end because the callback hasn't happened, and the callback can't happen because the loop hasn't ended. Commented Jul 5, 2017 at 23:57
  • In addition to your while loop going forever, you're also adding a new socket.on() event handler EVERY time through the while loop. You just can't use this type of structure in Javascript. You don't look checking something in Javascript. Instead, you register event handlers, respond to those events and check your state in those event handlers. Worst case, you might check some state on a timer. Commented Jul 6, 2017 at 0:49

1 Answer 1

0

You can't do this in a while loop, Javascript just doesn't work that way. A possible alternative approach:

// Notify the current leader
function notifyLeader(leader) {
    socket.broadcast.to(leader).emit('leader', { message: 'You are the leader for this round', options: 'THIS WOULD BE A SELECTION BUTTON FOR THE leaderSelection EVENT LISTENER'});
}

// Notify all users except the leader
function notifyUsers(users, leader) {
    users
    .filter(user => user !== leader)
    .forEach(user => {
        socket.broadcast.to(user).emit('user', { message: 'You are a user for this round'});
    });
}

// In a round of play, notify the leaders and users
// When the leaderSelection event comes in, start a new round
// with the next leader
function startRound(ids, leaderIndex) {
    notifyLeader(ids[index]);
    notifyUsers(ids, leaderIndex);
    socket.once('leaderSelection', () => {
        startRound(ids, ++leaderIndex);
    });
}

// Start the first round with leader 0
startRound(ids, 0);
Sign up to request clarification or add additional context in comments.

1 Comment

Cool, I'll check this out soon. Just wanted to acknowledge you and say thanks so far. This looks promising.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.