使用 CoffeeScript 的类和 jquery.transit 创建一个回调循环

Create a callback loop with CoffeeScript's classes and jquery.transit

本文关键字:一个 循环 回调 创建 CoffeeScript transit jquery 使用      更新时间:2023-09-26
使用 jquery.transit

我想使用 jquery.transit 的回调参数构建一个循环。我不想使用setTimeout()来避免可能的竞争条件。

以下代码有效:http://jsfiddle.net/2errn/

$ ->
  animate = () ->
    console.log "animate()"
    $(".rect").transition({x: 10}, animate)
  animate()

矩形只移动一次,但在控制台中很明显,该方法被多次输入。所以这行得通!为了使它更频繁地移动,我需要在 x 坐标中添加一个增量计数器,但这不是这里的问题。

我想将功能封装在一个类中,但在这里它失败了:http://jsfiddle.net/6A97m/1/

$ ->
  class Animator
    animate: ->
      console.log "animate()"
      $(".rect").transition({x: 10}, @animate)
    new Animator().animate()

在日志记录语句的输出停止之前,仅输入该函数两次。为什么?我该如何解决这个问题?

这只是一个未绑定的函数引用:

@animate

该引用没有绑定到它的特定@,因此在调用它时将选择@。特别是,@不会是您Animator实例,因此@animate第二次访问它时会undefined

如果您将console.log更改为以下内容:

console.log @, "animate()"

您会看到第一次调用@ animate实例时是您的Animator实例,但第二次调用时它是其他实例。

有多种解决方案:

  1. 使用绑定方法:

    animate: =>
      console.log "animate()"
      $(".rect").transition({x: 10}, @animate)
    

    演示:http://jsfiddle.net/ambiguous/3puUe/

  2. 使用 bind 传递时绑定animate

    animate: ->
      console.log "animate()"
      $(".rect").transition({x: 10}, @animate.bind(@))
    

    演示:http://jsfiddle.net/ambiguous/BPSa9/

  3. 使用旧的_this = this技巧手动设置适当的@

    animate: ->
      console.log "animate()"
      _this = @
      $(".rect").transition({x: 10}, -> _this.animate())
    

    演示:http://jsfiddle.net/ambiguous/p4z8x/

大多数工具包库都有自己的绑定方法,以防您无法保证Function.bind可用:_.bind$.proxy、...