1

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>

2
  • 1
    Your first setTimeout is not correctly closed... you provide it more than 2 arguments, which will be evaluated as arguments to pass to the callback. I don't think you intended that. Commented Feb 18, 2021 at 19:40
  • 4
    Do you know what the third (and fourth and so on) argument to setTimeout is used for? The output Hello 123, then Hello 567, then Hello makes sense, since the inner arguments need to be evaluated before the outer function call. This is always the case and is not specific to setTimeout. The only special thing about setTimeout is that a delay of 0 attempts to schedule function execution in the next event loop cycle. Commented Feb 18, 2021 at 19:41

3 Answers 3

4

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.

Sign up to request clarification or add additional context in comments.

Comments

1

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.

11 Comments

To clarify, the result of the second setTimeout (which is a timeout identifier), is needed for the root setTimeout as it's one of its parameters. //// Help me understand , this is where I got confused. Here the 3 rd alert should come as first & then second alert right?
I'm explaining the current behavior of your code which makes no sense. Could you explain what you are actually trying to achieve so I can make a better answer?
I'm trying to understand the concept of setTimeout in deeper :)
@HemaNandagopal “Here the 3 rd alert should come as first & then second alert right?” — No, the timeout with alert("Hello 123"); is evaluated before the one with alert("Hello 567");. If you expect it to be the other way around and still use this confusing structure with nested functions, move the ) after the second 0 to the end.
@GuerricP That page does show that additional parameters can be passed a little farther down in the "Parameter Values" section.
|
1

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>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.