Hema Nandagopal
Hema Nandagopal

Reputation: 678

setTimeout Functionality in JavaScript

I'm trying to understand the concept of setTimeout and I couldn't understand how it works. In the below example, when I gave the 1000 to the second setTimeout function I got the output as

1)Hello 567
2)Hello
3)Hello 123

But When I gave the setTimeout for all the functions as 0, it shows as

1)Hello 123
2)Hello 567
3)Hello

Initially, I assumed the innerfunction value is returned first then in the below case shouldn't be

1)Hello 567
2)Hello 123
3)Hello

Please help me understand

<!DOCTYPE html>
<html>

<body>

  <p>Click the button to wait 3 seconds, then alert "Hello".</p>

  <button onclick="myFunction()">Try it</button>

  <script>
    function myFunction() {
      setTimeout(function() {
        alert("Hello");
      }, 0, setTimeout(function() {
        alert("Hello 123");
      }, 0), setTimeout(function() {
        alert("Hello 567");
      }, 0));
    }
  </script>

</body>

</html>

Upvotes: 1

Views: 157

Answers (3)

ray
ray

Reputation: 27275

Not sure whether this was intentional or a typo, but you're passing more than two arguments to the first setTimeout. I've deconstructed your code for clarity. This is what you're doing:


function hello () {
  alert("Hello");
}

function hello123 () {
  alert("Hello 123");
}

function hello567 () {
  alert("Hello 567");
}

setTimeout(hello, 0, setTimeout(hello123, 0), setTimeout(hello567, 0));

You're passing 4 arguments to the outer setTimeout call. The last two are evaluated first to resolve their values before being passed to (the outer/first) setTimeout.

setTimeout returns an ID, so if the inner calls return 555555 and 999999 respectively, this is the equivalent of:

setTimeout(hello, 0, 555555, 999999)

And because the inner calls get evaluated first you see those alerts first if they all have the same delay1.

If you increase the delay on the inner timeouts you'll see their alerts after, because the outer one expires first.


1. Due to the way timeouts are handled in the javascript event loop, it's possible that these could appear in a different order. I'm ignoring those idiosyncracies for the purposes of this discussion.

Upvotes: 4

Scott Marcus
Scott Marcus

Reputation: 65853

You didn't close out the first setTimeout() call with ).

You can now see that they run in the sequence that they were invoked, which is the sequence that they are placed on the event queue.

<!DOCTYPE html>
<html>

<body>

  <p>Click the button to wait 3 seconds, then alert "Hello".</p>

  <button onclick="myFunction()">Try it</button>

  <script>
    function myFunction() {
      setTimeout(function() {
        alert("Hello 1");
      }, 0)
      , setTimeout(function() {
        alert("Hello 2");
      }, 0)
      , setTimeout(function() {
        alert("Hello 3");
      }, 0);
    }
  </script>

</body>

</html>

Upvotes: 1

Guerric P
Guerric P

Reputation: 31835

I don't know what you're expecting by passing a third and fourth parameter to setTimeout, but it obviously evaluates before the root setTimeout.

To clarify, the 3rd and 4th parameters of the root setTimeout are the results of other setTimeout calls, so they need to be evaluated first before their results are passed the the root setTimeout.

Upvotes: 1

Related Questions