Nodej上Backbone的延迟触发器

时间:2014-12-19 20:31:18

标签: javascript backbone.js coffeescript q rxjs

B = require 'backbone'
U = require 'underscore'

o = {}
U.extend o, B.Events
o.on 'e', console.log
setTimeout o.trigger, 5000, 'e', 'Hi!'

为什么Nodejs控制台没有记录上面延迟的Backbone #trigger

@Edit

Q = require 'q'

d = Q.defer()
d.promise.then console.log
setTimeout d.resolve, 5000, 'Hi!'

这完美无瑕。但是,如果Q #resolve被包含在下面的匿名函数中,为什么控制台不会记录,

setTimeout (-> d.resolve 'Hi!'), 5000

@Edit 2

实际上,包装版本Q #resolve在首次调用时也有效。

为什么简单版本Q #resolve在Backbone #trigger没有的情况下有效,这是唯一剩下的问题。

@Edit 3

R = require 'rx'

src = new R.BehaviorSubject 0
dst = src.map (v) -> v + 1
dst.subscribe console.log
setTimeout src.onNext, 5000, 1

Rx #onNext与Backbone #trigger有类似的问题和解决方案。

以上所有内容都可以来自不同的this上下文,例如裸版显示下面的问题,

o =
    f: ->
    g: -> @f()

setTimeout o.g

然后,

TypeError: Object [object Object] has no method 'f'

因此下面的包装版本可以通过。

setTimeout -> o.g()

下面显示this上下文切换导致问题,包装器解决它,

f = (g) -> g.apply @

o = 
    x: 'Hi!'
    g: -> console.log @x

f o.g # undefined
f -> o.g() # 'Hi!'

@Edit 4

此外,Coffeescript =>this的约束力在->以下,

x = 'Hi!'
o = f: => @x

console.log o.f() # Hi!
console.log -> o.f() # undefined

1 个答案:

答案 0 :(得分:1)

因为当您将o.trigger作为参数传递给setTimeout时,您执行trigger函数不是作为o对象的方法,而是在全局范围内执行它。在这种情况下,this内的trigger将指向o而不是global对象。

因此,在将o.trigger作为参数传递给setTimeout之前,您需要将其包装在匿名函数中。

不幸的是,我在Coffee Script中表现不佳,但我可以向您展示纯JavaScript中代码的样子:

var B, U, o;

B = require('backbone');
U = require('underscore');

o = {};

U.extend(o, B.Events);

o.on('e', console.log);

setTimeout(function () {
    o.trigger('e', 'Hi!');
}, 5000);

希望这会有所帮助。祝你好运。