Sign in to follow this  
Dan K

Passing Closed arguments to Timer

Recommended Posts

I am having a difficult time passing a variable to a me.timer.setTimeout... can it accept variables?  Specifically its a bit of a closure problem as well. 

I am trying to deploy units over set intervals of time. I have the units in an array with time offsets.  I thought I'd cycle through the array of units setting the timer event to the offset.  But when the timer event fires, it accesses the last known value on the closure variable.

for (let i = 0; i < this.unitList.length; i++) {

    var unitType = this.unitList[i].type;
    var delay = this.unitList[i].delay;
    var toBeCalled = function () {
            console.log("Deploying Unit: " + unitType);
            // this.deployUnit(unitType);
            this.deployUnit(unitType); // 'this'  here is the 'window' object because the timer comes from the window
    }.bind(this); // if you don't bind it to this. then the unitType won't be declared
    me.timer.setTimeout(toBeCalled, delay * 1000, true);
   // window.setTimeout(toBeCalled,delay*1000,[unitType]); // but this is not pausable and it can't access the deployUnit function because it is part of a class
}

Any ideas of improving the closure? or passing arguments to the function?  the window version allows arguments but I can't seem to reach my class instances... (in theory they have to be there somewhere)

 

Share this post


Link to post
Share on other sites

As with the nature of all things... Pluging at this for a few more hours finally yields an answer myself...  This is an interesting trick... The problem was that the timer object gets called from the 'window'  object where the application instance was difficult to find.  So instead, I pass the 'this' instance as the context variable, thus ensuring that I had the 'deployUnit' property availble to call when the setTimeout executed the toBeCalled() function.

 

var makeTimer = function(unitType,delay,context)
 {
     var localUnit = unitType;

     var toBeCalled = function () {
         console.log("Deploying Unit: " + localUnit);
         // this.deployUnit(unitType); //
         context.deployUnit(localUnit,context); // 'this'  here is the 'window' object because the timer comes from the window.
                                                // on top of that problem, I couldn't seem to access the AppJS.GameController object, so I just
                                                // passing int along in the parameter context.
     };//.bind(this); // eventually just removed the bind, because I was able to pass in the class pointer in the parameter 'context'
     me.timer.setTimeout(toBeCalled, delay * 1000, true);
 };
for (let i = 0; i < this.unitList.length; i++) {

    var unitType = this.unitList[i].type;
    var delay = this.unitList[i].delay;
    makeTimer(unitType,delay,this); //https://www.youtube.com/watch?v=-jysK0nlz7A  9.6: JavaScript Closure - p5.js Tutorial by the Coding Train
}

Share this post


Link to post
Share on other sites

Indeed this is a valid request and to be honest i don’t recall why arguments passlng has not been included when we implemented these functions, as this is indeed supported by the global « standard » ones.

i’m glad that you found a way to make it work for you (passing arguments to bind was another one), but i’ll look anyway into adding it to our setTimeout and setInterval methods.

Thanks ! 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.