node,require,singleton还是not singleton?

时间:2017-06-27 13:37:55

标签: node.js service module

我很震惊地发现"要求" in node默认创建一个单例。有人可能会认为许多人拥有他们需要的具有状态的模块,但是创建为单例,因此只要有多个并发用户就会中断应用程序。

我们遇到了相反的问题,需要创建一个非单身人士,我们不知道如何解决这个问题。

因为我的大脑是作为java开发人员连接的,所以我们所有的节点文件/模块都是这样定义的:

file playerService.js

const Player = require("./player")
class PlayerService {
  constructor(timeout) {
       // some stuff
  }
  updatePlayer(player) {
     // logic to lookup player in local array and change it for dev version.
     // test version would lookup player in DB and update it.
  }
}
module.exports = PlayerService

当我们想要使用它时,我们这样做:

someHandler.js

const PlayerService = require("./playerService")
const SomeService = require("./someService")
playerService = new PlayerService(3000)
// some code which gets a player
playerService.updatePlayer(somePlayer)

尽管requires()默认创建单例,但在上面的例子中,我猜它不会创建一个单例,因为每个websocket消息(在我们的例子中)将在堆栈中调用的每个模块中实例化一个新对象。这是一个很大的开销 - 为单个消息提供服务,服务可能会被实例化5次,因为有5个不同的子服务/辅助类相互调用并且都执行一个requires(),然后将其乘以并发用户,你会得到很多不必要的对象。

1)我们如何修改上述课程作为单身人士,因为服务没有状态?

2)是否存在全局导入或创建全局对象的概念,以便我们可以为特定的websocket连接和/或所有连接导入(也称为require)和/或实例化对象一次?我们没有index.js或类似的。对于堆栈中的每个js文件重新需要依赖模块/文件似乎很疯狂。请注意,我们查看了DI选项,但发现它们太神秘,无法理解如何使用它们,因为我们不是js gurus,尽管经过多年的尝试。

1 个答案:

答案 0 :(得分:2)

您只需在文件中创建一个实例并将其导出即可。

config.Filters.Add(new RequireHttpsAttribute());

在这种情况下,您可能希望为成员变量添加setter作为构造函数参数以确保封装。

另请注意,在javascript中使用let playerService = new PlayerService(); module.exports = playerService; 创建对象实例比传统的OOP语言更便宜,因为它的原型模型(more)。

所以当你真的需要新实例时(如你的代码中所见,你真的想要共享超时构造函数参数吗?),请不要犹豫,因为javascript对象在原型方法和现代引擎方面具有相当的内存效率优秀的垃圾收集器,以防止内存泄漏。