在node.js中构建单例的最佳实践

在node.js中构建单例的最佳实践,node.js,express,Node.js,Express,我正在尝试构建一个express应用程序,我需要创建一些单例(比如Sequelizer中的db对象) app.js app.use(...); app.use(...); var serviceLocator = { foo: require('foo'), bar: require('bar') }; //object holding singletons. app.use('/api/todo', new todoRoutes(serviceLocator)); todo

我正在尝试构建一个express应用程序,我需要创建一些单例(比如Sequelizer中的db对象)

app.js

app.use(...);
app.use(...);
var serviceLocator = { 
    foo: require('foo'),
    bar: require('bar')
}; //object holding singletons.
app.use('/api/todo', new todoRoutes(serviceLocator));
todoRoutes.js

module.exports = (serviceLocator) => {
   var router = express.Router();  

   router.get('/', (req,res,next) => {
       //use serviceLocator.foo
   });

   router.get('/:id',(req,res,next) => {
       //use serviceLocator.bar
   });
};
这是一种好的做法吗


(我也读过关于使用require缓存构建单例的内容,但我有一些担心,因为在官方文档中,他们说require“可能不会”返回同一个对象)。

我通常是怎么做的,看起来像这样:

app.js

app.use(...);
app.use(...);
var serviceLocator = { 
    foo: require('foo'),
    bar: require('bar')
}; //object holding singletons.
app.use('/api/todo', new todoRoutes(serviceLocator));
todoRoutes.js

module.exports = (serviceLocator) => {
   var router = express.Router();  

   router.get('/', (req,res,next) => {
       //use serviceLocator.foo
   });

   router.get('/:id',(req,res,next) => {
       //use serviceLocator.bar
   });
};
总的来说,就是添加一些中间件,将其添加到req中,req将通过管道为您提供。您也可以通过将它添加到
req.server.
或其他内容来命名它的名称空间

您还可以通过引入
uuid
并将ID附加到另一个中间件中的每个req来生成请求ID,以后可以在日志语句中使用,这样您就可以跟踪请求


或者,只需要将这些单例输入todoRoutes.js并直接使用它们。它们在您的服务器上是单例,所以我看不出有任何问题。

这里没有单例。每次调用该函数时,都会生成一个新的
路由器。如果它在一个闭包中捕获
serviceLocator
,那么就它而言,它是不是一个单例是无关紧要的。
todoRoutes()
当一个模块被缓存时,它返回的路由器实例不是单例,因为每次调用
newtodoroutes()
都返回一个新的
路由器。因此在本例中,返回到
module.exports
的匿名函数被缓存为一个模块,但是
路由器
没有被缓存,也不是一个单例。是的,但是我想使用的单例是foo和bar,它们在serviceLocator上注册。我不希望todoRoutes家是单身汉。如果我创建了另一个路由,比如导出为=(serviceLocator)=>{}的productRoutes,如果我在内部调用serviceLocator.foo,我想得到调用serviceLocator.foo inside todoRoutes时得到的相同对象。我想问的是,是否最好将我的所有单例保存在app.js中定义的对象中,并将该对象传递给需要使用单例的所有对象(如上所述),或者我应该指望使用模块缓存来创建单例。谢谢你的回答,但我正在搜索澄清的是,单例是否可以依赖Node.js模块缓存,或者当缓存清除时,可能会出现这样的情况,并且你可以得到一个新对象?这是我的“可选”答案,但很抱歉,我没有从原来的帖子中弄清楚一个问题。是的,当节点第一次启动时,它遵循创建模块对象并保持缓存的要求。我从来没有听说过有一次他们不小心去了,我现在在谷歌上找不到任何东西,看看是否有人报告过。除非你自己清理,否则它将留在那里,可以信赖。