I have some JavaScript code that looks like:
function statechangedPostQuestion()
{
//alert("statechangedPostQuestion");
if (xmlhttp.readyState==4)
{
var topicId = xmlhttp.responseText;
setTimeout("postinsql(topicId)",4000);
}
}
function postinsql(topicId)
{
//alert(topicId);
}
I get a error that topicId
is not defined
Everything was working before i used the setTimeout()
function.
I want my postinsql(topicId)
function to be called after some time.
What should i do?
I recently came across the unique situation of needing to use a
setTimeout
in a loop. Understanding this can help you understand how to pass parameters tosetTimeout
.Method 1
Use
forEach
andObject.keys
, as per Sukima's suggestion:I recommend this method.
Method 2
Use
bind
:JSFiddle: http://jsfiddle.net/MsBkW/
Method 3
Or if you can't use
forEach
orbind
, use an IIFE:Method 4
But if you don't care about IE < 10, then you could use Fabio's suggestion:
Method 5 (ES6)
Use a block scoped variable:
Though I would still recommend using
Object.keys
withforEach
in ES6.Hobblin already commented this on the question, but it should be an answer really!
Using
Function.prototype.bind()
is the cleanest and most flexible way to do this (with the added bonus of being able to set thethis
context):For more information see these MDN links:
https://developer.mozilla.org/en/docs/DOM/window.setTimeout#highlighter_547041 https://developer.mozilla.org/en/docs/JavaScript/Reference/Global_Objects/Function/bind#With_setTimeout
As there is a problem with the third optonal parameter in IE and using closures prevents us from changing the variables (in a loop for example) and still achieving the desired result, I suggest the following solution.
We can try using recursion like this:
We need to make sure that nothing else changes these variables and that we write a proper recursion condition to avoid infinite recursion.
This is a very old question with an already "correct" answer but I thought I'd mention another approach that nobody has mentioned here. This is copied and pasted from the excellent underscore library:
You can pass as many arguments as you'd like to the function called by setTimeout and as an added bonus (well, usually a bonus) the value of the arguments passed to your function are frozen when you call setTimeout, so if they change value at some point between when setTimeout() is called and when it times out, well... that's not so hideously frustrating anymore :)
Here's a fiddle where you can see what I mean.
@Jiri Vetyska thanks for the post, but there is something wrong in your example. I needed to pass the target which is hovered out (this) to a timed out function and I tried your approach. Tested in IE9 - does not work. I also made some research and it appears that as pointed here the third parameter is the script language being used. No mention about additional parameters.
So, I followed @meder's answer and solved my issue with this code:
Hope, this is usefull for someone else.
Some answers are correct but convoluted.
I am answering this again, 4 years later, because I still run into overly complex code to solve exactly this question. There IS an elegant solution.
First of all, do not pass in a string as the first parameter when calling setTimeout because it effectively invokes a call to the slow "eval" function.
So how do we pass in a parameter to a timeout function? By using closure:
Some have suggested using anonymous function when calling the timeout function:
The syntax works out. But by the time settopic is called, i.e. 4 seconds later, the XHR object may not be the same. Therefore it's important to pre-bind the variables.