0

I can't find anywhere on stack overflow or the internet a detailed guide to how javascript chooses its order of executing statements.

I have the following code. When I attach the debugger in the browser is appears to execute in order.

var cvs = document.getElementById('cvs');
cvs.width = window.innerWidth;
cvs.height = window.innerHeight;
var w = window;
w.onresize = (event) => {
    cvs.width = window.innerWidth;
    cvs.height = window.innerHeight;
};

However, the following bizarre behavior happens: the lines that begin with cvs.width execute just fine. However the line that begins with w.onresize doesn't work because w is null. However I can inspect the line var w = window; which executes prior, and I can see that both w and window are NOT null. So how is it that both w and window are not null, until the next line, at which time they are???

NOTE: People are responding about asynchronous execution. There's nothing asynchronous. The event handler is never attached in the first place, because w or window or null. This is not a concurrency problem, it's some type of script execution order and/or scoping problem.

The problem seems to be related to putting the script tag in the wrong place in the html? Here was my HTML:

html:

<html>
    <head></head>
<body>
    <div>
         <script src="bundle.js" />
    </div>
</body>
</html>

Moving the script out of the div changed the behavior of the "shroedinger's window".

Paul K
  • 154
  • 6
  • 1
    I can't reproduce this behavior. Please include the smallest complete HTML page that demonstrates it. – AuxTaco Mar 24 '18 at 05:37
  • [`` isn't valid HTML.](https://stackoverflow.com/q/69913/9029328) Given that HTML file, my browsers (Firefox 60, Chromium 65) won't run anything from `bundle.js`. – AuxTaco Mar 25 '18 at 02:33

2 Answers2

0

I was able to repair my problem by changing the order in which my bundle.js script was loaded on the .html page to the very end of the body. It was inside a div. After that, window had a value both times instead of only on lines beginning with var

I don't think there's any valid explanation to this problem. The only explanation is that this is standard javascript weirdness that veterans have simply trained themselves to never encounter.

It is very easy to demonstrate, over and over again, via debugger or console.log statements, using exactly the code I included, that certain variables like 'this', 'document' and 'window' can have values on one line of code, only to have a null value on literally the very next line of code.

If anybody has a link to documentation that could explain the strange synthesis of script load order, page load order, script execution order, and variable name scoping, I will mark it as the answer.

Paul K
  • 154
  • 6
0

I recall having confusion over a similar issue, and some of the explanations in this post really cleared it up: When is JavaScript synchronous?

As you'll gather from the post, Javascript is synchronous and single-threaded, meaning it generally executes your code in the order of you present your statements.

That said, the manner in which JS handles external events (e.g., callback from AJAX calls triggered by returned data or on click events) is asynchronous. This means that when the execution stack is cleared, the JS engine will check for events your code is listening for (e.g., data returned from an AJAX call or a button click), and execute the callback associated with that event if the event has been received -- the callback code will run synchronously. It will not interrupt any executing code, and no other code will execute until the callback's completion.

In sum, and as stated nicely in the post provided, it could be accurate to say that "JavaScript is synchronous and single-threaded with various callback mechanisms."

Greg Brodzik
  • 1,765
  • 7
  • 9
  • The problem is not that the event never fires (it doesn't) but that the window is null when it tries to attach the event. There's nothing asynchronous here. – Paul K Mar 24 '18 at 14:23