How can I pass a parameter to a setTimeout() callb

2018-12-31 03:33发布

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?

21条回答
心情的温度
2楼-- · 2018-12-31 04:00

The answer by David Meister seems to take care of parameters that may change immediately after the call to setTimeout() but before the anonymous function is called. But it's too cumbersome and not very obvious. I discovered an elegant way of doing pretty much the same thing using IIFE (immediately inviked function expression).

In the example below, the currentList variable is passed to the IIFE, which saves it in its closure, until the delayed function is invoked. Even if the variable currentList changes immediately after the code shown, the setInterval() will do the right thing.

Without this IIFE technique, the setTimeout() function will definitely get called for each h2 element in the DOM, but all those calls will see only the text value of the last h2 element.

<script>
  // Wait for the document to load.
  $(document).ready(function() {
  $("h2").each(function (index) {

    currentList = $(this).text();

    (function (param1, param2) {
        setTimeout(function() {
            $("span").text(param1 + ' : ' + param2 );
        }, param1 * 1000);

    })(index, currentList);
  });
</script>
查看更多
路过你的时光
3楼-- · 2018-12-31 04:04

The easiest cross browser solution for supporting parameters in setTimeout:

setTimeout(function() {
    postinsql(topicId);
}, 4000)

If you don't mind not supporting IE 9 and lower:

setTimeout(postinsql, 4000, topicId);

setTimeout desktop browser compatibility

setTimeout mobile browser compatibility

https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout

查看更多
还给你的自由
4楼-- · 2018-12-31 04:04

How i resolved this stage ?

just like that :

setTimeout((function(_deepFunction ,_deepData){
    var _deepResultFunction = function _deepResultFunction(){
          _deepFunction(_deepData);
    };
    return _deepResultFunction;
})(fromOuterFunction, fromOuterData ) , 1000  );

setTimeout wait a reference to a function, so i created it in a closure, which interprete my data and return a function with a good instance of my data !

Maybe you can improve this part :

_deepFunction(_deepData);

// change to something like :
_deepFunction.apply(contextFromParams , args); 

I tested it on chrome, firefox and IE and it execute well, i don't know about performance but i needed it to be working.

a sample test :

myDelay_function = function(fn , params , ctxt , _time){
setTimeout((function(_deepFunction ,_deepData, _deepCtxt){
            var _deepResultFunction = function _deepResultFunction(){
                //_deepFunction(_deepData);
                _deepFunction.call(  _deepCtxt , _deepData);
            };
        return _deepResultFunction;
    })(fn , params , ctxt)
, _time) 
};

// the function to be used :
myFunc = function(param){ console.log(param + this.name) }
// note that we call this.name

// a context object :
myObjet = {
    id : "myId" , 
    name : "myName"
}

// setting a parmeter
myParamter = "I am the outer parameter : ";

//and now let's make the call :
myDelay_function(myFunc , myParamter  , myObjet , 1000)

// this will produce this result on the console line :
// I am the outer parameter : myName

Maybe you can change the signature to make it more complient :

myNass_setTimeOut = function (fn , _time , params , ctxt ){
return setTimeout((function(_deepFunction ,_deepData, _deepCtxt){
            var _deepResultFunction = function _deepResultFunction(){
                //_deepFunction(_deepData);
                _deepFunction.apply(  _deepCtxt , _deepData);
            };
        return _deepResultFunction;
    })(fn , params , ctxt)
, _time) 
};

// and try again :
for(var i=0; i<10; i++){
   myNass_setTimeOut(console.log ,1000 , [i] , console)
}

And finaly to answer the original question :

 myNass_setTimeOut( postinsql, 4000, topicId );

Hope it can help !

ps : sorry but english it's not my mother tongue !

查看更多
登录 后发表回答