Coffeescript在类中设置间隔

Coffeescript在类中设置间隔,coffeescript,setinterval,Coffeescript,Setinterval,上周我开始写coffeescript,因为我正在编写一个新的Play20网站,其中coffeescript是标准的。我想每5分钟更新一次类中的getData函数,但setInterval函数不绑定到我的类。仅当它第一次调用getData时,因为“this”对象仍然是可访问的,因为setUpdateInterval()函数是从构造函数中调用的 但是在第一次调用之后,setInterval不再与小部件实例有任何连接,并且不知道this.getData()函数是什么(以及如何访问它) 有人知道怎么做吗

上周我开始写coffeescript,因为我正在编写一个新的Play20网站,其中coffeescript是标准的。我想每5分钟更新一次类中的getData函数,但setInterval函数不绑定到我的类。仅当它第一次调用getData时,因为“this”对象仍然是可访问的,因为setUpdateInterval()函数是从构造函数中调用的

但是在第一次调用之后,setInterval不再与小部件实例有任何连接,并且不知道this.getData()函数是什么(以及如何访问它)

有人知道怎么做吗

这是我的密码:

class Widget
  constructor: (@name) ->
    this.setUpdateInterval()

  getData: ->
    console.log "get Data by Ajax"

  setUpdateInterval: (widget) ->
    setInterval( this.getData(), 3000000 )

问题是您正在执行函数,而不是向其传递引用

现在,听起来您还需要保留实例的范围<代码>执行和
=>
可以帮助完成这一任务

 setUpdateInterval: (widget) ->
    setInterval (do =>
      @getData), 3000000
    true
编译成

Widget.prototype.setUpdateInterval = function(widget) {
      var _this = this;
      setInterval((function() {
        return _this.getData;
      })(), 3000000);
      return true;
    };
您将注意到代码执行一个自调用函数,该函数返回一个函数,该函数围绕
this
创建一个闭包,将其锁定在回调的范围内(如
this

还请注意,您不需要将小部件传递给该方法(您在任何地方都没有使用它),您可以在构造函数中调用该函数来设置间隔。不管你做什么,你只想调用这个方法一次。您可以将函数的内容放入构造函数中


最后,由于coffeescript返回所有函数的最后一条语句的值,因此我在其中抛出了一个
true
,但这可能不是必需的。

现在需要一些Javascript魔术

这几乎适用于所有浏览器(猜猜哪一个不适用),因此 函数必须以不同的方式绑定。一些咖啡脚本魔术:

callback = => @getData

这在节点中也很方便。这是塔斯社不同的回答

class Widget
  constructor: (@options = {}) ->
    @options.interval ?= 1000
    @setInterval()

  timer: ->
    console.log 'do something'

  setInterval: ->
    cb = @timer.bind @
    setInterval cb, @options.interval

w = new Widget()

您可以执行绑定调用,如
cb=@getData.bind@
,也不需要
setInterval
行中的括号…更多咖啡+1,我可能比我更喜欢这个答案,除了它在IE中不起作用。谢谢,代码完全符合我的要求(在Chrome中)!“callback=->that.getData.call(that)”似乎无法编译。下一个问题,不同的绑定是指我需要两个绑定,一个用于除IE之外的所有浏览器,一个用于IE的特殊绑定,还是只需要最后一个绑定?@Tass当然,但这不是coffeescript风格;)使用fat arrow(绑定实例方法)查看我的解决方案。
class Widget
  constructor: (@options = {}) ->
    @options.interval ?= 1000
    @setInterval()

  timer: ->
    console.log 'do something'

  setInterval: ->
    cb = @timer.bind @
    setInterval cb, @options.interval

w = new Widget()