避免重新评估和动态卸载用“require”调用的对象

Avoiding re-evaluation and dynamically unloading objects called with `require`

本文关键字:卸载 require 对象 调用 动态 新评估 评估      更新时间:2023-09-26

我正在研究nodejs模块系统是如何工作的。

到目前为止,我发现了以下文献:

  1. https://nodejs.org/api/modules.html
  2. http://fredkschott.com/post/2014/06/require-and-the-module-system/
  3. http://www.bennadel.com/blog/2169-where-does-node-js-and-require-look-for-modules.htm

它帮助我理解了几点,但仍然有这些问题:

  • 如果我在一个模块内有一个昂贵的资源(比如说数据库池连接),我如何确保通过再次要求该模块,我不会重新评估资源
  • 一旦我已经调用了一次性资源的"require",我如何动态卸载它

这很重要,因为我有一些场景要求我确保我有一个数据库池的实例。正因为如此,我导出的模块能够接收参数,而不仅仅需要昂贵的资源。

非常感谢您的指导。

Alon Salont在这里编写了一份关于理解NodeJS中的exports的卓越指南(当你调用require()时,你会访问它):http://bites.goodeggs.com/posts/export-this/#singleton

如果你研究模块可以导出的选项列表,你会发现问题的答案取决于模块的编写方式。当您调用require时,NodeJS将查找加载在其缓存中的模块,如果它已经在其他地方加载了模块,则返回它。

这意味着,如果您选择导出Singleton模式、进行monkey修补或创建全局对象(在您的情况下,我建议只创建第一个),则只会创建/存在一个共享对象。Singleton模式非常适合于数据库连接等需要由多个模块共享的情况。尽管有些人认为通过父/调用方"注入"这些依赖关系更好,但这是一种并非所有人都认同的哲学观点,软件开发人员广泛使用singleton来执行此类共享服务任务。

如果导出一个函数,通常是构造函数,require()仍然只返回一个对该函数的共享引用。然而,在这种情况下,引用是对函数的引用,而不是函数返回的内容。require()实际上并没有为你调用函数,它只是给了你一个对它的引用。要在这里做任何实际的工作,你现在必须调用函数,这意味着requires这个东西的每个模块都将有它自己的模块提供的任何类的实例。这种模式是更传统的模式,其中需要类实例/是目标。大多数NPM模块都属于这一类,尽管这并不意味着在您的情况下单例是个坏主意。