0

I was writing a long polling script and ran into a too much recursion error which hung the browser. My goal is to call the same function every 1000ms using setTimeout(). Yes, I could use setInterval() but it is going to be a long polling script and will be waiting for a server response.

I fixed this by removing the () from the function I was calling within the same function.

My script looks like:

function messagePolling(){
    console.log("polled")
    setTimeout(messagePolling(),1000) // <--- removing `()` from the function works as intended 
} 

messagePolling();

What is the logic behind this? messagePolling is a function after all isn't it.

Ikhlak S.
  • 8,578
  • 10
  • 57
  • 77
  • 2
    `messagePolling` is a reference to a function. `messagePolling()` **invokes** the function. You should know that since you have `messagePolling();` in the last line of your code snippet ;) And I'm sure you have passed the return value of a function to other functions before, i.e. `foo(bar())`. This is will call `bar` and pass the return value to `foo`. That's how function invocation works in JavaScript. – Felix Kling Sep 24 '16 at 19:15
  • See e.g. [this question](http://stackoverflow.com/questions/1190642/how-can-i-pass-a-parameter-to-a-settimeout-callback) or [many other duplicates](https://www.google.de/webhp#q=javascript+settimeout+pass+function+site:stackoverflow.com) – ASDFGerte Sep 24 '16 at 19:29

4 Answers4

5

You're absolutely right - messagePolling is a function. However, messagePolling() is not a function. You can see that right in your console:

// assume messagePolling is a function that doesn't return anything
messagePolling() // -> undefined

So, when you do this:

setTimeout(messagePolling(), 1000)

You're really doing this:

setTimeout(undefined, 1000)

But when you do this:

setTimeout(messagePolling, 1000)

You're actually passing the function to setTimeout. Then setTimeout will know to run the function you passed - messagePolling - later on. It won't work if it decides to call undefined (the result of messagePolling()) later, right?

Nebula
  • 6,614
  • 4
  • 20
  • 40
1

Written as setTimeout(messagePolling(),1000) the function is executed immediately and a setTimeout is set to call undefined (the value returned by your function) after one second. (this should actually throw an error if ran inside Node.js, as undefined is not a valid function)

Written as setTimeout(messagePolling,1000) the setTimeout is set to call your function after one second.

XCS
  • 27,244
  • 26
  • 101
  • 151
0

When you type messagePolling you are passing the function to setTimeout as a parameter. This is the standard way to use setTimeout.

When you type messagePolling() you are executing the function and passing the return value to setTimeout

That being said, this code looks odd to me. This function just runs itself. It's going to keep running itself indefinitely if you do this.

jlogan
  • 947
  • 6
  • 9
0

Anywhere a function name contains "()" it is executed immediately except when it is wrapped in quotes i.e is a string.

Taiti
  • 375
  • 2
  • 6
  • In which case, it is not a _function_ but a _string_. That string will only be then used to execute the function if it gets passed through `eval` which is exactly what `setTimeout` does if you do pass it a string. – VLAZ Sep 24 '16 at 19:15
  • E.g var func = "myFunction()". setTimout("myFunction()",1000) will still be executed. but not instantly. In short I meant function name as a string or variable can not run on its own when just placed in your code without using other functions. – Taiti Sep 24 '16 at 19:30
  • _It isn't a function_. That's the point your `func` variable contains a string. It just _happens_ to be code that you can execute, however, you make it sound like it's inherently a delayed execution. It isn't. If you have `setTimeout("a = b + c; console.log(a)")` that will also work, but _only_ because it gets passed through `eval`. If you pass the same string through something that does not do `eval` it will never work. – VLAZ Sep 24 '16 at 19:34
  • Yes it is not a function but a string containing function name and "()" which can be executed as a function so eval("myFunction()")==myFunction() – Taiti Sep 24 '16 at 19:41
  • I guess what is strange about this answer is that you can say this about any other kind of expression: *"Anywhere you have `1 + 1`, the numbers will be added and you get `2`, except when it is wrapped in quotes, i.e. is a string."*. So, how is having code inside a string relevant here at all? Doesn't really provide any value IMO. – Felix Kling Sep 24 '16 at 23:26
  • Example is var a = myFunction() will be executed while var a = "myFunction()" will not be executed. It doesn't matter where myFunction() is typed. – Taiti Sep 26 '16 at 21:54