使用类处理NodeJS 4中的循环依赖项[重复]

Posted

技术标签:

【中文标题】使用类处理NodeJS 4中的循环依赖项[重复]【英文标题】:Handling circular dependencies in NodeJS 4 with classes [duplicate] 【发布时间】:2016-11-03 13:04:56 【问题描述】:

我在执行 module.exports = 时遇到循环依赖问题。

这是一个例子。 ClassC 需要 ClassB,ClassB 需要 ClassA,ClassA 需要 ClassC。在 main.js 中,我们只需创建一个新的 ClassC 实例并调用该方法,这将执行一系列调用:

/* classA.js */
'use strict';

const ClassC = require('./classC.js');
class ClassA 
    foo() 
        console.log('ClassA.foo');
        var classC = new ClassC();
        classC.bar();
    


module.exports = ClassA;

/* classB.js */
'use strict';

const ClassA = require('./classA.js');
class ClassB 
    foo() 
        console.log('ClassB.foo');
        var classA = new ClassA();
        classA.foo();
    


module.exports = ClassB;

/* classC.js */
'use strict';

const ClassB = require('./classB.js');
class ClassC 
    foo() 
        console.log('ClassC.foo');
        var classB = new ClassB();
        classB.foo();
    

    bar() 
        console.log('ClassC.bar');
    


module.exports = ClassC;

/* main.js */
'use strict';

const ClassC = require('./classC.js');

var classC = new ClassC();
classC.foo();

所以当我调用 node main.js 时,我得到一个明显的错误,即 ClassC 未解析。

D:\Projects\test-circular-reference-es6\classA.js:8
        var classC = new ClassC();
                     ^
TypeError: ClassC is not a function
    at ClassA.foo (D:\Projects\test-circular-reference-es6\classA.js:8:22)
    at ClassB.foo (D:\Projects\test-circular-reference-es6\classB.js:9:16)
    at ClassC.foo (D:\Projects\test-circular-reference-es6\classC.js:9:16)
    at Object.<anonymous> (D:\Projects\test-circular-reference-es6\main.js:7:8)
    at Module._compile (module.js:409:26)
    at Object.Module._extensions..js (module.js:416:10)
    at Module.load (module.js:343:32)
    at Function.Module._load (module.js:300:12)
    at Function.Module.runMain (module.js:441:10)
    at startup (node.js:139:18)

发生这种情况是因为当 ClassA 中需要 ClassC 时,它仍然是 ClassC 加载的过程,因此返回了一个空对象,后来在 classC.js 结束时,module.exports 被 ClassC 覆盖,而对空对象的引用在 classA.js 中保持原样。

所以问题是如何处理这个问题,在 NodeJS 4.x (ES6) 中同时拥有循环引用和导出类的最佳做法是什么?

从我的角度来看,我看到了以下可能的方式:

    不要覆盖 module.exports 并执行 module.exports.class = ClassC; 之类的操作,然后像 new ClassC.class(); 一样进行实例化,但这通常也会为继承和笨拙的代码带来更多困难。 改用 TypeScript,因为它会处理这些东西。

欢迎提出任何建议。

【问题讨论】:

改用 TypeScript,因为它会处理这些东西。真的吗? @nils 并在每次遇到新问题时更改语言! 我猜有一个变体#3,在 ClassC 的构造函数中执行 ClassB 的 require。到构造函数调用的那一刻,具有 ClassB 的对象将已经在缓存中,因此可以使用。问题是代码变得非常混乱。 如果您使用 ES6 导入,这将起作用。它不能与module.exports = … 一起使用。 @Bergi,如果您的评论是针对我的,那么您可能错了。它适用于 node.js 的导出。我也会争论这个问题的重复状态,因为这里讨论的是 ES6 类。 【参考方案1】:

尝试将 require 调用移动到具有类定义的文件末尾。这是工作示例:

// a.js
class A 
    foo() 
        var c = new C();
        c.foo();
    


module.exports = A;
const C = require('./c.js');

// b.js
class B 
    foo() 
        var c = new C();
        c.foo();
    


module.exports = B;
const C = require('./c.js');

// c.js
class C 
    foo() 
        var a = new A();
        a.foo();
    


module.exports = C;
const A = require('./a.js');

// main.js
const C = require('./c.js');
const B = require('./b.js');

const c = new C();
const b = new B();

c.foo();
b.foo();

注意该调用 c.foo() 将导致最大调用堆栈错误。但是所有的类引用都如你所愿地解决了。

【讨论】:

是的,它会起作用的,谢谢!但一个小缺点是我不能将所有要求放在文件末尾,例如对于继承,我需要在类声明之前以任何方式要求基类。看起来有些要求将位于文件的顶部,而有些则位于文件末尾。除此之外,这看起来不错。 @Aides:无论如何,你不能有循环继承。父类不应导入其子类。 @Aides 是的,分离依赖块有一点警告。但这是在定义时解决 node.js 中循环依赖的唯一方法。

以上是关于使用类处理NodeJS 4中的循环依赖项[重复]的主要内容,如果未能解决你的问题,请参考以下文章

gradle - 依赖项中的库重复

从类中分解所有依赖项的最简单、最快的方法

Python3基础 使用for循环 删除一个列表中的重复项

使用 Spring Boot 服务作为批处理作业中的依赖项的空指针异常

spring boot应用程序作为maven依赖项[重复]

如何在 Maven 中解压 AAR 依赖类?