JavaScript Pub/Sub属性访问问题

JavaScript Pub/Sub property access issue

本文关键字:访问 问题 属性 Sub Pub JavaScript      更新时间:2023-09-26

我有一个奇怪的问题,希望大家都能帮忙。

项目详细信息

我正在为一个包含pubsub.subscribe_once()方法的大型应用程序开发一个简单的pub/sub实现。此方法允许创建一次性订阅,这意味着创建一个通用订阅,然后一旦触发正确的"发布"事件并运行订阅回调,订阅就会自行删除。

subscribe_once: function(topic, func) {
    var sub = pubsub.subscribe(topic, func),
        old_func = sub.func;
    // rewrite our subscription's method to remove itself after invocation
    sub.func = function() {
        // call the original function
        old_func.apply(this);
        // remove subscription from topic
        pubsub.unsubscribe(sub);
    };
    return sub;
}

问题

我似乎对这个过程的记忆流有某种问题。(为了更好地理解下面的解释,我建议你边看下面的jsfiddle演示。)我创建了一个subscribe_once("someevent")订阅,然后启动publish("someevent")。当调用发布方法时,您会看到主题哈希表包含一个"someevent"键,该键引用一组Subscription对象。事实上,如果您引用主题["someevent"],您会看到一个具有单个Subscription的数组。但是,如果您引用了主题,您会看到"someevent"键,但数组为空

通过注释掉pubsub.unsubscribe(sub);,问题就消除了,即使在我们运行console.log(topics)之后才启动此函数。

此外,这似乎与给定浏览器"线程"console.log的方式无关;试试console.log(topics, topics[topic], topics, topics[topic]),你会得到同样的结果。

演示:http://jsfiddle.net/4Ab6c/

如有任何帮助,我们将不胜感激!谢谢

我仍在寻找一些文档来支持我,但我怀疑控制台中显示的对象正在对topics对象执行惰性评估。在sub被推送到数组后,我将console.log(topics)添加到subscribe方法中,得到的结果与您的"但不在此"日志相同。当我将fiddle pubsub.publish('someevent')的最后一行封装在setTimeout中,并在publish回调运行之前打开Object树时,它会在数组中显示订阅,即使在回调运行之后,它也会保持这种状态。如果在回调运行之前我没有打开控制台中的对象树,那么我会看到空数组。

我会继续搜索一篇博客文章或一些证实懒惰评估正在发生的事情。

为了防止我还没有把它说得足够明显,我所说的懒惰是指,直到在控制台中单击打开树视图,控制台才收集对象的详细信息。

我在Chrome上工作。

更新

我在Firefox上也发现了类似的行为。Firefox识别出数组中有一个对象,但如果在发布启动之前没有深入到数组中,那么对数组的深入将为空。

我从你的评论中更新了小提琴:

http://jsfiddle.net/4Ab6c/2/

请尝试这个:

  • 运行fiddle并展开第一个console.log的对象树。在发布事件触发之前,我将其设置为5秒的超时,但您可以将其设置得更长或更短,这取决于您能多快到达控制台并单击检查器打开。

  • 您应该如预期的那样在数组中看到订阅对象。

  • 清理控制台,然后重新演奏小提琴。这一次,在发布事件激发并且所有代码都已运行完毕之后,才打开对象检查器。

  • 现在,当您打开第一个console.log的对象检查器时,您不应该在数组中看到订阅事件。

更新2这里有一个更简单的小提琴,它表现出同样的行为:

http://jsfiddle.net/4Ab6c/3/

如果你在第二个出现之前先展开,那么你会得到foo:bar。如果你在第二个出现后先扩展,你会得到foo:baz。

更新3

瞧,另一个SO问题是关于懒惰评估的动议。