Ian*_*son 2 javascript node.js typescript nestjs
此处提供了Repo来突出显示该问题。
我遇到了竞争条件问题。我创建了一个ConfigModule- 这有一个forRoot和一个forChild。
设置文件forRoot的加载.env并forChild在另一个模块中使用它。
问题是forChild之前调用过forRoot。由于尚未首先执行,因此将ConfigService注入缺少的配置。forRoot
> AppModule > ConfigModule.forRoot InstanceModule >
> ConfigModule.forChild
Run Code Online (Sandbox Code Playgroud)
我放置了一些简单的console.log命令来输出这个
I am in Config Module FOR CHILD
I am in Config Module FOR ROOT
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,forChild首先执行的是,我尝试使用forwardRef,但没有成功。
如果你让应用程序运行你会看到
[2019-03-24T11:49:33.602] [ERROR] ConfigService - There are missing mandatory configuration: Missing PORT
[2019-03-24T11:49:33.602] [FATAL] ConfigService - Missing mandatory configuration, cannot continue!, exiting
Run Code Online (Sandbox Code Playgroud)
这是因为我检查了一些process.env可用的文件,这些文件是在 via 中加载的dotenv。当然,因为forRoot不会首先执行,所以forChild会返回它自己的新实例ConfigService。
ConfigService验证环境变量的可用性。
所以,基本上, 是在 之前forChild执行并返回自己的。ConfigServiceforRoot
为了使其工作,如果您注释掉内部InstanceModule,AppModule那么它将自动开始侦听并从环境变量返回端口号。
当然,因为InstanceModule使用forChild- 存在竞争条件。
1)Nest建立一个依赖图并根据该图实例化给定的模块及其提供者。导入的顺序或动态模块方法的命名 ( forRoot/ forChild) 不会影响实例化的顺序。
2)当您创建动态模块时,每个模块将是它自己的实例,它们不会像常规模块那样是单例。在您的情况下,您将创建两个不同的ConfigModule实例,并使用它创建两个不同的ConfigService实例;因此他们不会共享您的.env配置。这是行不通的,与实例化顺序无关。
看看nestjs/typeorm包装。在底层,它创建一个共享,它在/TypeOrmCoreModule创建的不同动态模块实例之间共享。为了使其能够同时共享和动态,它必须被制作出来。在您的情况下,由于您的导入中没有任何配置,因此您只需将整个全局化,然后省略导入,因为无论如何它们都是全局可用的。TypeOrmModule.forRootTypeOrmModule.forChild@GlobalforChildConfigModuleforChild()ConfigService
如果您不希望您的服务全局可用,您可以在启动过程后初始化您的服务,例如在您的AppModule方法中onModuleInit。
| 归档时间: |
|
| 查看次数: |
8212 次 |
| 最近记录: |