【问题标题】:Delayed trigger for Backbone on NodejsNodejs 上 Backbone 的延迟触发
【发布时间】:2025-11-23 02:00:01
【问题描述】:
B = require 'backbone'
U = require 'underscore'

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

为什么Nodejs 控制台没有记录上述延迟的主干#trigger

@编辑

Q = require 'q'

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

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

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

@编辑 2

实际上,包装版本 Q #resolve 如果第一次被调用也可以工作。

为什么普通版 Q #resolve 有效,而 Backbone #trigger 无效,这是唯一剩下的问题。

@编辑 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!'

@编辑 4

此外,Coffeescript => 绑定到 this 变化为下面的 ->

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

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

【问题讨论】:

    标签: javascript backbone.js coffeescript q rxjs


    【解决方案1】:

    因为当您将o.trigger 作为参数传递给setTimeout 时,您执行trigger 函数不是作为o 对象的方法,而是在全局范围内执行它。也就是说,在这种情况下,trigger 中的 this 将不指向 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);
    

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

    【讨论】:

    • @sof 正如我之前所说,我对 Coffee Script 的了解很差,而且我从未使用过 q 或 rx 库。所以恐怕我没有时间去挖掘所有这些东西。
    最近更新 更多