Coffeescript timer and 'this' callback pointer

I have a problem with the browser counting 'this'. In the following example, a call to pingMe () in abc will wait 1 second, and then the browser will say that Object DOMWindow does not have a func method. Instead of allowing the 'this' instance of the ABC (abc) class, it instead solves the DOMWindow as if the object were not involved. I clearly don't understand how setTimeout works in relation to the callback scope. Any suggestions how can I make this callback successful?

class ABC @func = null constructor: (func) -> @func = func pingMe: -> setTimeout(doPing, 1000) doPing = -> @func() abc = new ABC -> alert "HI" abc.pingMe() 
+6
coffeescript
source share
3 answers

This code works for me.

 class ABC @func = null constructor: (func) -> @func = func pingMe: -> setTimeout => @doPing() , 1000 doPing: -> @func() abc = new ABC -> alert "HI" abc.pingMe() 

Your doPing method was defined by doPing = -> , while the rest all use name: -> , I changed it that way. pingMe uses => to create an unnamed function and @doPing to bind this to the function.

Not sure if this is correct, I rarely use JavaScript. But I hope this can give you direction for further study.

+10
source share

An alternative solution that is closer to what you are doing in ES5 is this:

 pingMe: -> setTimeout(@doPing.bind(@), 1000) 

or if you want to keep in parentheses:

 pingMe: -> setTimeout (@doPing.bind @), 1000 

Please note that bind is ES5, therefore it is only available in IE from version 9.


Also note: you should avoid the temptation to try:

  setTimeout(@doPing.bind @, 1000) # BAD! or setTimeout @doPing.bind @, 1000 # BAD! 

because both of them pass the number as the second argument to bind , not setTimeout !

+1
source share

Perhaps for clarity, you can bind the doPing method. It will look a little cleaner and FWIW, I think it better expresses what you want to achieve.

 class ABC @func = null constructor: (func) -> @func = func pingMe: -> setTimeout => @doPing, 1000 doPing: => @func() abc = new ABC -> alert "HI" abc.pingMe() 
0
source share

All Articles