【问题标题】:pubsub design pattern for nodejsnodejs的pubsub设计模式
【发布时间】:2013-08-13 19:23:11
【问题描述】:

我正在寻找一个可以在 nodejs 或类似方式中使用的简单 pubsub 实现。 我只在服务器端需要它,所以不需要花哨的 faye。

我想拥有以下能力:

模块 A 发布事件“X” 模块 B 订阅事件“X”而不知道模块 A 的任何信息(可能发送的参数除外)

我测试了这个简单的实现 https://github.com/federico-lox/pubsub.js/blob/master/src/pubsub.js,它确实可以发挥作用

我目前使用简单 pubsub 实现的问题是我不能简单地订阅事件。

如果模块 A 发布了一个事件,但模块 B 在任何地方都不需要,它将永远不会收到来自模块 A 的事件。模块 A 在发布事件之前需要模块 B 时,它当然可以工作。但这很不愉快。

所以简而言之: 我正在寻找一种与 nodejs 搭配得很好并允许我非常独立地(松散耦合)编写可以通过事件进行通信的模块的设计模式。你们推荐什么方法?

我也查看了nodejs eventemitter,但找不到很好的用法(也许我只是看不到它?)

更新: 我进一步研究了 eventemitter 并想出了这个:

emitter.js

var events = require('events');
var emitter = new events.EventEmitter;

module.exports = emitter;

moduleA.js

var emitter = require('./emitter.js');
require('./moduleB.js'); // this shows off my problem

emitter.emit('moduleA');

moduleB.js

var emitter = require('./emitter.js');

emitter.on('moduleA', function () {
    console.log('reacted to event from moduleA');
});

这显示了我的“问题”,但我不确定是否有解决办法。也许我的方法是完全错误的,但在浏览器端这应该可以工作,因为所有代码都是在页面加载时预加载的

【问题讨论】:

  • 您的方法应该有效,但是如果您在 moduleB.js 之前使用该代码加载 moduleA.js ,它可能会在 B 确实监听它之前发出事件。尝试交换他们的订单
  • 这正是我目前所看到的。当模块 B 侦听模块 A 但在模块 A 发出事件之前未加载时,它根本不会捕获事件。这是非常合乎逻辑的,因为如果某个地方不需要,模块就无法监听事件。但我仍然认为这很糟糕,并且会导致错误,有人很容易忘记“预加载”一个模块
  • 我猜一个实际的用例只会包含异步事件,即当模块执行时没有立即触发,所以加载顺序并不重要。
  • 这实际上不是真的。我有一个用例,我正好遇到了这个问题。这是一个简单的 websocket 应用程序。当第一个用户连接时,我会触发一个“连接”事件,但处理连接事件的模块在任何地方都不需要。所以实际上没有人订阅该事件。我现在做的是“预加载”模块。我在一个 json 文件中定义了哪些模块应该在应用程序启动时预加载。这适用于我的情况。
  • 是的,当然它们都需要在启动时由主脚本加载。我的观点是加载顺序无关紧要,因为当第一个信号发出时(当套接字连接时)异步所有模块都已经加载并且不能错过它。

标签: javascript node.js design-patterns


【解决方案1】:

这是一个简单的模板,用于基本事件管道使用节点的核心events 模块。

//modA.js
var events = require('events');
var emitter = new events.EventEmitter;

function funcA() {
  console.log('mod@.funcA executing');
  emitter.emit('funcA');
}

module.exports = {
  funcA: funcA,
  emitter: emitter
};

//modB.js
var events = require('events');
var emitter = new events.EventEmitter;

function funcB() {
  console.log('modB.funcB executing');
  emitter.emit('funcB');
}

module.exports = {
  funcB: funcB,
  emitter: emitter
};

//glue.js
var modA = require('./modA');
var modB = require('./modB');
modA.emitter.on('funcA', modB.funcB);
modA.funcA();

node glue.js
mod@.funcA executing
modB.funcB executing

【讨论】:

  • …和modB.emitter.on('funcB', modA.funcA);
  • @Bergi 除非你想要一个诚实的 Stackoverflow 错误。 :-)
  • EventEmitter 不是异步的吗?
  • 本身不是,不是。这都是没有 I/O 的纯 javascript。
猜你喜欢
  • 1970-01-01
  • 2011-08-24
  • 1970-01-01
  • 2019-11-06
  • 1970-01-01
  • 2021-12-28
  • 1970-01-01
  • 2021-06-30
  • 2017-10-10
相关资源
最近更新 更多