javascript websockets – control initial connection/when does onOpen get bound

JavaScript is single threaded which means the network connection can’t be established until the current scope of execution completes and the network execution gets a chance to run. The scope of execution could be the current function (the connect function in the example below). So, you could miss the onopen event if you bind to it very late on using a setTimeout e.g. in this example you can miss the event:

View: http://jsbin.com/ulihup/edit#javascript,html,live

Code:

var ws = null;

function connect() {
  ws = new WebSocket('ws://ws.pusherapp.com:80/app/a42751cdeb5eb77a6889?client=js&version=1.10');
  setTimeout(bindEvents, 1000);
  setReadyState();
}

function bindEvents() {
  ws.onopen = function() {
    log('onopen called');
    setReadyState();
  };
}

function setReadyState() {
  log('ws.readyState: ' + ws.readyState);
}

function log(msg) {
  if(document.body) {
    var text = document.createTextNode(msg);
    document.body.appendChild(text);
  }
}

connect();

If you run the example you may well see that the ‘onopen called’ log line is never output. This is because we missed the event.

However, if you keep the new WebSocket(...) and the binding to the onopen event in the same scope of execution then there’s no chance you’ll miss the event.

For more information on scope of execution and how these are queued, scheduled and processed take a look at John Resig’s post on Timers in JavaScript.

Leave a Comment