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
?
Q = require 'q'
d = Q.defer()
d.promise.then console.log
setTimeout d.resolve, 5000, 'Hi!'
这完美无瑕。但是,如果Q #resolve
被包含在下面的匿名函数中,为什么控制台不会记录,
setTimeout (-> d.resolve 'Hi!'), 5000
实际上,包装版本Q #resolve
在首次调用时也有效。
为什么简单版本Q #resolve
在Backbone #trigger
没有的情况下有效,这是唯一剩下的问题。
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!'
此外,Coffeescript =>
与this
的约束力在->
以下,
x = 'Hi!'
o = f: => @x
console.log o.f() # Hi!
console.log -> o.f() # undefined
答案 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);
希望这会有所帮助。祝你好运。