flimflam57
flimflam57

Reputation: 1334

Not understanding this setTimeout in JS

I thought I understood how the setTimeout method worked, but this is confusing me.

test.html (I'm purposefully loading the test.js file before the jQuery file for demonstration. Let's say the jQuery file is hosted locally).

<body>
// ...code
<div id="area"></div>
// ...code

<script src="test.js"></script>
<script src="jquery.js"></script>
</body>

test.js

$('#area').text('hello');

I understand in this case "hello" won't get printed on the browser because jQuery is being loaded after the test.js file. Switching the order of these files solves the problem. But if I leave the order alone, and alter the test.js file, a setTimeout makes it work:

function wait() {
    if(window.jQuery) {
        $('#area').text("hello");
    }
    else
    {
        setTimeout(wait, 10);
    }
}

wait();

In this case the "hello" text gets printed on the browser. But I'm sort of scratching my head because somehow the jQuery file does get loaded. But how? Why doesn't the test.js file get caught in an infinite loop forever checking to see if jQuery has loaded? I'd be grateful for some insight on the mechanics of what's going on.

Upvotes: 1

Views: 102

Answers (5)

Dmytro Shevchenko
Dmytro Shevchenko

Reputation: 34591

Why doesn't the test.js file get caught in an infinite loop forever checking to see if jQuery has loaded?

setTimeout works asynchronously. It does not pause the browser. It simply asks it to execute a certain function after a certain amount of milliseconds.

jquery.js gets loaded and executed inbetween wait() invocations.

Upvotes: 2

sudheer
sudheer

Reputation: 165

setTimeOut method runs in a separate queue called asynchronous callback. so once the interpreter comes to this line, the code is moved to a separate queue and continues with it parsing(which then executes jQuery.js). After this is executed , it looks for items the asynchronous queue to check if the timeout is completed and then executed method inside setTimeout. By this time jQuery.js is already loaded.

More on this https://youtu.be/8aGhZQkoFbQ

Upvotes: 1

Shadow Wizard
Shadow Wizard

Reputation: 66389

JavaScript is not pre-compiled. It's working "on the fly".

You can add code on the fly, whenever you want, and this includes loading whole libraries. Once the browser loaded an external JS file it parses it, and it's all ready to use.

So if you wait for jQuery, and do have the proper code to load it, it will eventually be loaded by the browser and work.

Upvotes: 0

Paul Roub
Paul Roub

Reputation: 36438

There would be an infinite loop if jQuery never loaded. But in the normal case:

  1. The first time through, jQuery isn't loaded, so we setTimeout() 1a. Other things happen in the meantime, including loading of resources like jQuery
  2. 10ms later, we check again.
  3. Is jQuery loaded now? If not, set a timeout and go back to step two
  4. After some number of retries, jQuery does load, and we're off.

The better way to do all of this, of course, would be to

  1. Load jQuery first
  2. Run your wait() function in a ready() handler so it doesn't run until it's needed.
<script src="jquery.js"></script>
<script src="test.js"></script>
// test.js
$(document).ready( 
  function() 
  {
     $('#area').text("hello");
  }
);

Upvotes: 4

Pointy
Pointy

Reputation: 413720

Without that setTimeout() code, when the contents of "test.js" are evaluated the browser will immediately run into the problem of $ (jQuery) not being defined. With the setTimeout(), however, the code does not attempt to use the global jQuery symbols until it verifies that the symbols are defined.

Without the setTimeout the code fails with a runtime error. The code in the other version explicitly tests for that failure possibility to avoid it.

Upvotes: 2

Related Questions