如何在 node.js 域中添加全局发射器?

Posted

技术标签:

【中文标题】如何在 node.js 域中添加全局发射器?【英文标题】:How to add in node.js domain global emitter? 【发布时间】:2013-07-25 23:17:57 【问题描述】:

在我的 node.js 应用程序中,我曾经按域处理错误。 该应用的架构如下所示:

    控制器。快速路由调用控制器方法

    控制器调用服务并使用模型

    服务调用存储库

(其实和DDD很像)。

因此,控制器创建域,并在域中运行其实际主体。如果出现问题,服务会抛出异常。控制器还监听域错误并处理它们。它非常舒服,因为我不需要担心在所有服务的方法调用堆栈中出现错误——我只是抛出一个异常并且可以确定它会被控制器捕获。

但是我遇到了与使用 PostgreSQL 相关的问题。 我使用 node-postgres 模块并在单独的 js 文件中创建 pg.Client,因此 pg.Client 就像为所有人共享(否则,在每个查询上创建 pg.Client 会打开许多​​与 postgres 的活动连接)。

问题在于,当 pg.Client 在单独的文件中定义时,它就像一个全局对象,并且不包含在控制器中创建的域范围内。所以 pg.Client 回调抛出的异常不会被域捕获。

我将展示简化的请求处理方式以使其清楚。假设用户想通过 userId 登录:

    在最初创建的 pg.Client 中某处

    获取请求来快递,快递调用路由方法

    路由调用一些控制器的方法

    控制器创建域并在 «domain.run» 中调用服务

    服务调用存储库

    Repository 获取之前创建的pg.Client,并调用sql查询方法

    sql查询方法的结果放入回调中(所以这个回调被pg.Client调用)

    然后在服务中处理回调,我们检查我们得到 null 而不是用户模型(因为给定 userId 的 db 中没有这样的用户)并抛出异常

因此该异常不会在域中捕获。 从技术上讲,我们需要使用节点域的 «add» 方法并添加 pg.Client,但是我说 pg.Client 是共享的,因此它将添加到不同的并发域中。

我将列出一些代码示例以使其更清楚。 是UserService的简化方法:

 login: function (email) 

                    var userRepository = new UserRepository();
                    userRepository.findByEmail(email, function (model) 
                        if (model == null)
                           throw new Error('No such user');
                    );

            

因此,该方法«login»在域中被调用。但它创建了 userRepository,调用 findByEmail 方法,该方法将使用位于域范围之外的共享 pg.Client,这就是域中不会捕获异常的原因。

任何想法如何修复它并将 pg.Client 放入域中?

【问题讨论】:

【参考方案1】:

我解决了这个问题。 我在活动域的范围内创建 EventEmitter 并听让我们说“onCallback”事件。 在查询方法的回调中(未与域连接,因为 pg.Client 有点全局并且位于域之外)我发出 EventEmitter 的 «onCallback»。

【讨论】:

以上是关于如何在 node.js 域中添加全局发射器?的主要内容,如果未能解决你的问题,请参考以下文章

node.js socket.io 如何发射到特定的客户端?

Websocket 内存泄漏 node.js。事件发射器?

Node.js 的进程间和服务器间事件发射器/侦听器?

如何从回调函数中修改全局变量。在 node.js 中

如何在 node.js (express) 中全局设置内容类型

Node.js自定义对象事件监听与发射