【问题标题】:Coffeescript setInterval in class课堂上的 Coffeescript setInterval
【发布时间】:2012-05-09 12:09:44
【问题描述】:

上周我开始编写coffeescript,因为我正在编写一个以coffeescript 为标准的新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 )

【问题讨论】:

    标签: coffeescript setinterval


    【解决方案1】:

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

    class Widget
      constructor: (@name) ->
        this.setUpdateInterval()
    
      getData: ->
        console.log "get Data by Ajax"
    
      setUpdateInterval: (widget) ->
        callback = @getData.bind(this)
        setInterval( callback, 3000000 )
    

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

    callback = => @getData
    

    【讨论】:

    • 您可以像cb = @getData.bind @ 一样进行绑定调用,而且您也不需要setInterval 行上的括号...更多咖啡。 +1,我可能比我更喜欢这个答案,除了它在 IE 中不起作用。
    • 谢谢,代码完全符合我的要求(在 Chrome 中)! 'callback = -> that.getData.call(that)' 的一件事似乎无法编译。下一个问题,不同地绑定是指我需要两个绑定,一个用于除 IE 之外的所有浏览器,一个用于 IE 专用,还是只需要最后一个绑定?
    • @Tass 当然,但这不是咖啡脚本式的 ;)
    • 使用胖箭头(绑定实例方法)看我的解决方案。
    【解决方案2】:

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

    现在,听起来您还需要保留实例的范围。 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 周围创建一个闭包,将其锁定在回调范围内(如_this

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

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

    【讨论】:

      【解决方案3】:

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

      class Widget
        constructor: (@options = {}) ->
          @options.interval ?= 1000
          @setInterval()
      
        timer: ->
          console.log 'do something'
      
        setInterval: ->
          cb = @timer.bind @
          setInterval cb, @options.interval
      
      w = new Widget()
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多