8

I'm using a framework which features auto-connecting to server on page load. I can disable it by passing options arguments, but the line that confuses me is this:

You can prevent this initial socket from connecting automatically by disabling io.sails.autoConnect before the first cycle of the event loop elapses.

My questions are:

  1. When does the first cycle of the event loop elapses?
  2. Is this behaviour the same across ALL modern (IE9+) browsers?
  3. I have a bunch of scripts (in <body>) loading between the lib and my entry file. Does this affect when the first cycle elapses? EDIT: Yes, it does.
  4. How can I ensure my code runs before the first cycle elapses?
  5. Is this kind of implementation of auto-connect considered good practice?
Paul Sweatte
  • 24,148
  • 7
  • 127
  • 265
Howie
  • 2,760
  • 6
  • 32
  • 60
  • Afair, "the event loop" starts when a browser window/tab is opened. The first cycle *that the page scripts use* I'm not so sure however – Bergi Aug 07 '14 at 11:06
  • 1
    The next line of that comment in the example is "This usually means putting it directly underneath the – Matt Browne Aug 07 '14 at 11:38
  • As to auto-connect, the docs say it queues the messages and sends them in order for you as soon as it connects, so unless that brief delay between when you ask for the messages to be sent and when they're actually sent is a problem, it sounds like a fine practice to me. – Matt Browne Aug 07 '14 at 11:41
  • @MattBrowne I have decided to use the auto-connect feature in my favour because my knowledge of browsers inner workings is shoddy and my _gut_ simply doesn't trust that this will work 100% reliably. I.e. if there's a delay that happens after the SDK loads but before my script with the options loads, the first cycle will already pass and my options will be ignored. – Howie Aug 07 '14 at 11:47
  • 1
    Well I think that putting it right after the SDK script should be safe because script tags are loaded synchronously by default. This link may be helpful: http://stackoverflow.com/questions/12729438/when-is-the-javascript-event-loop-triggered-in-a-html-page – Matt Browne Aug 07 '14 at 11:49

1 Answers1

2

The documentation for the source file is a little more explicit; it says "This can be disabled or configured by setting io.socket.options within the first cycle of the event loop."

Basically what's happening is that there exists within the library a setTimeout(fn, 0) call, which is idiomatic for starting a parallel process. However, in the JS standards it's explicitly stated that JS is single-threaded: in other words, even though setTimeout and setInterval are asynchronous they are not actually parallel in the sense that any of their code will be executing simultaneously with any other code. So they wait until the current function is over before they execute. This queueing mechanism is known as the JavaScript event loop.

I believe that what you are asked to do by the script author is to modify the source to include the relevant change, perhaps at the bottom of the file for your convenience.

It is also likely that a similar effect will be achieved by putting a <script> tag underneath the one that loads the given JS. This has not been explicitly standardized by HTML 4, but may be implicitly standardized in the new HTML 5 spec (it's a complicated interaction between different parts of the specs).

In terms of HTML5, it looks like the current specs say that there is a afterscriptexecute event and a load event which occur immediately after any remote script is loaded (or, if it's an inline script, the load event is scheduled as a task -- I am not sure when those occur). So you might be able to guarantee it without modifying the script by instead doing:

<script>
function do_not_autoload() { /* ... */ }
</script>
<script onload="do_not_autoload()" src="./path/to/sails.io.js"></script>

but I'm not sure what the compatibility table for script@onload is going to look like.

I made you a jsfiddle which can be used to grab a 'fingerprint' for different browsers to get an idea of what evaluation orders are out there in the wild. The * is the document.body.onload event. On my system it produces:

Firefox 32.0.3 : cafdbe*
Chrome 37.0.2062 : cafd*be
IE 11.0.9600 : cafd*be

In other words,

CR Drost
  • 9,637
  • 1
  • 25
  • 36
  • I'm not so sure what the difference between the `a` and `d` script is - what do you want to show by duplicating it? – Bergi Oct 06 '14 at 18:19
  • @Bergi I need to duplicate some code so that we can answer the question of "does the event loop happen between these?" (this would be a CABFDE order) and adding at least the e() setTimeout let me see whether setTimeout is FIFO or LIFO. Part of the HTML4 spec seems to suggest that this should start 'ADCF...' possibly with B and E thrown in there or held until after. Copy-paste was the easiest way to resolve all of those questions simultaneously. – CR Drost Oct 06 '14 at 18:25
  • I see what you mean, although the second script would not need another timeout and another immediate-written script. See http://jsfiddle.net/z2f5a1pk/2/ – Bergi Oct 06 '14 at 18:32