CoffeeScript中的多个回调

时间:2012-02-21 09:58:26

标签: javascript jquery coffeescript

我正在努力找出将多个回调串起来的正确行为。

class Person

  move_head: ->
     head.animate({
        left: x,
     },{
        complete: @move_foot,
     });

  move_foot: ->
     foot.animate({
        left: x,
     },{
        complete: @move_arm,
     });

  move_arm: ->
     arm.animate({
        left: x,
     },{
        complete: something_else,
     });

现在的问题是,头部动画很好,调用脚。脚也很好动画。问题是当脚完成时,它不会使手臂动起来。我无法弄清楚问题可能是什么。我猜测它可能与范围问题有关。

1 个答案:

答案 0 :(得分:5)

使用胖箭头=>this绑定到当前上下文:

move_head: =>
  // ...
move_foot: =>
  // ...
move_arm: =>
  // ...

更新:这是一个简短的解释:

javascript中最大的问题之一是this。在方法(例如move_head)中,this是您的Person实例,如果您将其称为new Person().move_head()。但它不一定是。例如,如果您使用new Person().move_head.call(null)进行调用,则this将为null

但最大的问题是当你进入function时,就像jQuery动画调用的complete回调一样,this不再绑定到你的对象!它可能与window绑定,但不是肯定的。那么在你的情况下会发生的事情是你给jQuery一个@move_foot(或者真的,this.move_foot)的引用。这个调用似乎有效,因为你的动画完成了。但是当jQuery调用该函数时,它将不再知道this应该是你的Person。因此,当您告诉它然后转到@move_arm时,它会在某个其他对象(可能是move_arm)上查找方法window

解决此问题的一种常用方法是在拨打电话之前保存对this的引用,例如var self = this,然后在回调中引用该绑定变量self代替。

你可以使用这种技术,它没有任何问题。类似的东西:

move_head: ->
  self = this
  head.animate(..., complete: self.move_foot)

但CS通过给你一个胖箭头this来为你做这个(=>的绑定)。

胖箭说:“此方法中涉及this的所有内容都应引用此对象。”