nestjs 全栈进阶--Module和Provider的循环依赖

58 阅读2分钟

 视频教程

21_nest中的循环依赖_哔哩哔哩_bilibili

1. 循环依赖

当两个类相互依赖时,就会发生循环依赖。比如 A 类需要 B 类,B 类也需要 A 类。Nest中 模块之间和 提供器之间也可能会出现循环依赖。

nest new dependency -p pnpm
nest g res aaa --no-spec
nest g res bbb --no-spec
pnpm start:dev

2. Module 循环依赖

你会发现程序报错了

意思是在解析 BbbModule 的时候,它的第一个 imports 是 undefined。

这有两个原因,一个是这个值本来就是 undefined,第二个就是形成了循环依赖。因为 Nest 创建 Module 的时候会递归创建它的依赖,而它的依赖又依赖了这个 Module,所以没法创建成功,拿到的就是 undefined。

如何解决?答案使用 forwardRef

现在程序就正常了

3. Provider循环依赖 controller 中相互引用

首先我们先导出,然后在 controller 中相互引用

我们的程序并不会报错,浏览器也正常输出

4. Provider循环依赖 service 中相互引用

如何解决?答案还是使用 forwardRef

这时候就不能用默认的注入方式了,需要通过 @Inject 手动指定 forwardRef 的方式注入。

可以看到 我们这里没有报错但是你在浏览器访问时

这是为什么呢?大家要注意,你这样调用可不行哟,这样就成了无限递归调用了,因为你 a 的service调用b的findAll方法时,b里的findAll又在调用a得到findAll,这就是无限递归。


好了,我们看了特殊会出错的情况,我们在来验证下,正常的依赖情况,我们在b的service中再写个handler

然后我们改下AaaService

这里有这么多的原因是,我们之前在AaaController和BbbController里的代码并没有删除

那么我们不在资源模块中时呢?

nest g service ccc --no-spec --flat
nest g service ddd --no-spec --flat

分别创建 ccc 和 ddd 两个 service,--no-spec 是不生成测试文件,--flat 是平铺。就会创建这两个 service,并在 AppModule 引入

然后我们分别修改下

保存后,可以看到报错了

解决办法,还是使用forwardRef

保存后,之前的报错就没了,然后我们去AppController写个方法使用下