3

我上周开始编写咖啡脚本,因为我正在编写一个以咖啡脚本为标准的新 Play20 网站。我想每 5 分钟更新一次班级中的 getData 函数,但 setInterval 函数没有绑定到我的班级。只有第一次调用 getData,因为“this”对象仍然可以访问,因为 setUpdateInterval() 函数是从构造函数中调用的。

但是在第一次调用之后,setInterval 与 Widget 实例不再有任何联系,并且不知道 this.getData() 函数是什么(以及如何到达它)。

有人知道该怎么做吗?

这是我的代码:

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

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

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

3 回答 3

7

现在这里需要一些 Javascript 魔法。参考

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

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

  setUpdateInterval: (widget) ->
    callback = @getData.bind(this)
    setInterval( callback, 3000000 )

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

callback = => @getData
于 2012-05-09T12:18:23.997 回答
3

问题是您正在执行该函数,而不是传递对它的引用。

现在,听起来您还需要保留实例的范围。 do并且=>可以提供帮助。

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

编译为

Widget.prototype.setUpdateInterval = function(widget) {
      var _this = this;
      setInterval((function() {
        return _this.getData;
      })(), 3000000);
      return true;
    };

您会注意到代码执行了一个自调用函数,该函数返回一个函数,该函数在 周围创建一个闭包this,并将其锁定在回调的范围内(as _this

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

最后,由于 coffeescript 从所有函数返回最后一条语句的值,我true在其中抛出一个,但这可能没有必要。

于 2012-05-09T12:12:29.990 回答
0

这在节点中也很方便。这是塔斯答案的变体。

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

  timer: ->
    console.log 'do something'

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

w = new Widget()
于 2013-05-04T15:07:19.340 回答