0

I'm confused on the way the method setTimeout is working with JS. why is it when I call the firstFunction the setTimeout only runs once AND when I call the secondFunction it keeps on calling the function.

I would expect consistency. Either the firstFunction, setTimeout would continue calling the log function OR in the secondFunction the setTimeout will only call the secondFunction once and finish.

var firstFunction = function(){
    var log = console.log('hello')
    setTimeout(log, 2000);
}

firstFunction();

var secondFunction = function(str){
    console.log(str)
    setTimeout("secondFunction('test')", 2000);
}

secondFunction('test');
Seena Khoee
  • 29
  • 1
  • 8
  • 2
    because `secondFunction` calls `secondFunction` in the setTimeout - but `firstFunction` calls the function `log` (whatever that is) in the setTimeout – Jaromanda X Jan 20 '17 at 00:01
  • Timeout are just that - *timeouts*. They don't run indefinitely (until you clear them), they run **once**. In the case of your second example, the timeout calls the function itself which simulates the effect of an *interval* (`setInterval`) and calls indefinitely. – Andrew Li Jan 20 '17 at 00:03
  • Also in your first example, `console.log` doesn't return anything so your timeout is set up incorrectly – Andrew Li Jan 20 '17 at 00:04

1 Answers1

3

The first snippet is incorrect. console.log('hello') runs immediately and the timeout doesn't trigger anything because in your example log is undefined.

Here is what a working example would look like:

var firstFunction = function(){
    var log = function() { console.log('hello'); };
    setTimeout(log, 2000);
}

firstFunction();

The second snippet loops forever because you are telling it to do the following:

1) Run the statement secondFunction('test')

2) Log the parameter and set a time out for 2 seconds.

3) once the timeout ends, run the statement secondFunction('test')

4) Log the parameter and set a time out for 2 seconds.

5) once the timeout ends, run the statement secondFunction('test')

...

n) Repeats forever

var secondFunction = function(str){
    console.log(str)
    setTimeout("secondFunction('test')", 2000);
}

secondFunction('test');

Notice that in the first example, the timeout doesnt call the firstFunction again, it calls a function called log, and log does not create another timeout callback, so it only runs once.

**Edit - How to call it not using a string as the function parameter? **

Also its probably not preferable to call this with a string. Call it using a reference to a function. This is demonstrated in the first example where the function log is declared and passed into setTimeout. But you could also do it this way:

var thirdFunction = function(){
    setTimeout(function() { console.log('Hello World'); }, 1000);
}

thirdFunction();
GantTheWanderer
  • 1,255
  • 1
  • 11
  • 19
  • I see. Appreciate that.... Also is there any way I can code that so I don't need to put the function in a string? – Seena Khoee Jan 20 '17 at 00:14
  • See update to answer, examples 1 and 3 demonstrate how to call it not using a string. – GantTheWanderer Jan 20 '17 at 00:17
  • I'm curious if you can please explain the difference between calling it using a string and calling it using a reference to a function – Seena Khoee Jan 20 '17 at 00:35
  • When its a string, javascript tries to 'eval' the string as executable javascript. This is slow because it has to parse the string into javascript and then execute the code. In the other case, we can pass in an actual function object to be run instead. Read more here: http://stackoverflow.com/questions/4506074/settimeout-with-string-or-anonymous-function-reference-speedwise – GantTheWanderer Jan 20 '17 at 00:40