发布/订阅 / 事件驱动架构 是客户端和服务器端JavaScript世界中的常见做法。我被委托使用Dojo作为前端和node.js作为后端来设计一个非常大的Web应用程序。发布/订阅似乎非常吸引人,因为它允许团队之间进行大量并行处理。但我担心会有性能后果。
"我是一名有用的助手,可以翻译文本。
我有一个关于 JavaScript 中事件和事件处理程序成本的一般性问题。我已经看到了 this, this, this, 甚至 this 和 this。但我似乎仍然没有看到一个通用的答案。不考虑框架,假设我们有2个方法。
publish() //Like jQuery's / Dojo's trigger(), EventEmitter's emit()
和
subscribe() //Like jQuery's / Dojo's / EventEmiter's / DOM's on() connect() live() addEventListener()
问题1:每个事件触发器的成本是多少?
案例1:强调发布/订阅的更干净(松散耦合)代码
object.publish('message1', data);
object.publish('message2', data);
...
object.publish('message100', data);
//All these are in separate files / modules
subscribe (object, 'message1', function (data) { A()...})
subscribe (object, 'message2', function (data) { B()...})
subscribe (object, 'message100', function (data) { Z()...})
案例二:代码耦合度高!但它是否更具性能?
data.message = 'message1'
object.publish('message', data)
subscribe (object, 'message', function (data) {
switch (data) {
case 'message1':
A();
break();
case 'message2':
B();
break();
...
case 'message100':
Z();
break();
}
})
问题2:每个事件监听器的成本是多少?
object.publish('event', data);
案例1:再次强调Pub/Sub的干净(松散耦合)代码
//A.js
subscribe (object, 'event', function (data) {
A();
});
//B.js
subscribe (object, 'event', function (data) {
B();
});
//C.js
subscribe (object, 'event', function (data) {
C();
});
案例2:再次,紧密耦合的代码!但它是否更具性能?
subscribe (object, 'event', function (data) {
A();
B();
C();
});
问题1:有人能指导我在客户端(使用DOMEvents或Custom Events)、服务器端(EventEmitter等)进行的相关研究和性能测试吗?这只是一个简单的例子,但应用程序很快就可以扩展到数千个这样的调用。如果没有,如何测试自己是否存在明显的性能下降?也许可以使用jsperf之类的工具?是否有任何理论基础可以了解为什么其中一个更加高效?
问题2:如果Case 1更高效,那么编写松散耦合代码的最佳方法是什么?有没有找到折中方案的方法?像 Case 1 一样编写代码,但使用一些中间编译/构建过程将其转换为 Case 2 (类似于Google Closure编译器在其他性能情况下所做的)。例如使用[Esprima]。我不想让构建过程变得更加复杂。如果有任何性能提升,这是否值得?
问题3:最后,虽然我在这里寻求非常具体的JavaScript答案,但了解其他语言/环境中的性能成本可能会有所帮助。事实上,在大多数情况下,事件都是由硬件触发的(使用中断的概念),这对答案有什么贡献吗?
感谢所有坚持到这个问题结尾的人!!!非常感谢!!!
EventEmitter
中还是在接收事件后,都会有一些东西在事件名称上进行切换。真正的诀窍是消除对字符串的切换 - 回调是一种方法,但不是另一个答案使用它们的方式。理论上,我认为基于数字的消息系统会更快。实现on(messageId: Number, ...)
而不是on(messageType: String, ...)
。然后,您可以使用messageId
作为回调数组中的偏移量:callbacks[messageId]
。 - David Griffin