1

To clarify my question, here are two examples in Javascript-esque pseudo-code. Here are the same examples but with a bit more code to contextualize them: http://pastebin.com/fRjW5qp6

See how I'm using conditionals to prevent sockets from triggering the important event logic after they've already triggered it once (e.g. I set socket.loginBuilt to true after the event listener has been triggered).

socket.on('login screen built', socketLoginScreenBuilt);

  function socketLoginScreenBuilt() {
    // See how I'm using this conditional to prevent sockets from triggering the important event logic after they've already triggered it once (since I set socket.loginBuilt to true in the logic)
    if (!socket.loginBuilt) {
      numberOfSocketsWithBuiltLoginScreens++;
      socket.loginBuilt = true;

      if (numberOfSocketsWithBuiltLoginScreens === io.sockets.sockets.length) {
        app.emit('all login screens built')
      }
    }
  }

  socket.on('login credentials', socketLoginCredentials);
  
  function socketLoginCredentials(credentials) {
    if (readyForLoginCredentials) {
      socket.username = credentials.username;
      socket.password = credentials.password;
      
      socket.emit('user stored data', socket.userData);
    }
  }
});

------------------- OR -------------------

Notice how I'm not using the conditionals I used above because I remove the listeners after the functions run for the first time. In that way I'll be certain that a socket won't trigger the important event logic multiple times.

socket.on('login screen built', socketLoginScreenBuilt);  

function socketLoginScreenBuilt() {
  // Notice how I'm not using a conditional here because I remove the 'login screen built' listener after this function is first ran. In that way I'll be certain that a socket won't trigger the important event logic multiple times
  numberOfSocketsWithBuiltLoginScreens++;
  socket.loginBuilt = true;

  if (numberOfSocketsWithBuiltLoginScreens === io.sockets.sockets.length) {
    app.emit('all login screens built')
  }
  
  socket.removeListener('login screen built', socketLoginScreenBuilt);
}

socket.on('login credentials', socketLoginCredentials);

function socketLoginCredentials(credentials) {

  socket.username = credentials.username;
  socket.password = credentials.password;

  socket.emit('user stored data', socket.userData);
  socket.removeListener('login credentials', socketLoginCredentials);
}
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
cyclingLinguist
  • 334
  • 1
  • 5
  • 16

1 Answers1

1

I want to clarify 2 things:

  • Node.js is event-driven.
  • Global variables are evil (there's a C/C++ tag but they make the point)

So, in order to keep your code clean and, well, up-to-standards, you should use event-driven approach rather than global variables.

BTW in both cases you do use global variable numberOfSocketsWithBuiltLoginScreens.

Community
  • 1
  • 1
Alexander Mikhalchenko
  • 4,525
  • 3
  • 32
  • 56
  • Part of my hesitation for removing the listeners is that Node.js doesn't seem to complain if I try to remove a listener that isn't even attached to an emitter. That lack of notification feels like it might make debugging more difficult. Do you know of anyway I could mitigate this problem? Perhaps I could write a custom removeListener function that checks if the event name I enter is attached to the listener. – cyclingLinguist Jan 05 '16 at 00:40
  • 1
    @EstanislaoStan I don't think the lack of a notification is a problem. If an error was thrown or whatever when removing the non-added listener, that would be much worse :) – Alexander Mikhalchenko Jan 05 '16 at 09:30