Javascript 使用require的Dojo循环依赖

Javascript 使用require的Dojo循环依赖,javascript,dojo,Javascript,Dojo,我正在使用dojo,这些是我的模块- 'myview/ModuleA' --requires--> 'myview/ModuleB' 'myview/ModuleB' --requires--> 'myview/ModuleC' 'myview/ModuleC' --requires--> 'myview/ModuleD' 现在,我正在努力使 'myview/ModuleD' --requires--> 'myview/ModuleB' 但是当代码尝试用TypeErr

我正在使用dojo,这些是我的模块-

'myview/ModuleA' --requires--> 'myview/ModuleB'
'myview/ModuleB' --requires--> 'myview/ModuleC'
'myview/ModuleC' --requires--> 'myview/ModuleD'
现在,我正在努力使

'myview/ModuleD' --requires--> 'myview/ModuleB'
但是当代码尝试用
TypeError将
ModuleB
实例化为
new ModuleB()
时,模块化失败:ModuleB不是构造函数
。 我看到
ModuleB
只是
对象
,而不是
模块化
中的
函数。所以我知道我为什么会出错。我还意识到这可能是因为循环依赖,这就是
ModuleB
未加载到
ModuleD
中的原因

我可以通过从
ModuleD
define(…)
的requires列表中删除
ModuleB
来解决这个问题,并在实例化之前使用
require()
加载它。这很有效

我的问题是,这是一种正确的方法来处理模块的循环依赖关系,还是有更好的/不同的方法可以推荐

谢谢,

对于循环依赖关系,要求“动态”而不是执行
定义时间是正确的方法。
这里解释如下:

如果您定义了一个循环依赖项(“a”需要“b”和“b”需要“a”),那么在这种情况下,当调用“b”的模块函数时,它将得到一个未定义的“a”值。“b”可以在稍后使用require()方法定义模块后获取“a”(请确保将require指定为依赖项,以便使用正确的上下文查找“a”)


重要提示:在构建时,您必须在构建概要文件中指定需要的所有组件。否则,它们将不会包含在要生成的文件列表中。

即使RequireJS对循环依赖项有适当的解决方法,如:

//Inside b.js:
define(["require", "a"],
    function(require, a) {
        //"a" in this case will be null if "a" also asked for "b",
        //a circular dependency.
        return function(title) {
            return require("a").doSomething();
        }
    }
);
()

经常使用循环依赖关系*意味着您的设计需要改进。拥有两个相互依赖的模块意味着你有一个高度耦合的设计,这应该会在每个开发人员的头脑中敲响警钟。有关更多信息,请阅读以下内容:

正确的解决方案是,如果A依赖于B,而B依赖于A,则B使用的所有代码都在一个不同的模块中分离,我们称之为C。然后我们可以像这样解耦模块:

//Inside b.js:
define(["require", "a"],
    function(require, a) {
        //"a" in this case will be null if "a" also asked for "b",
        //a circular dependency.
        return function(title) {
            return require("a").doSomething();
        }
    }
);
  • A取决于B
  • A取决于C
  • B取决于C
这样,您就可以通过使用中间程序来解耦代码



*循环依赖性并不总是坏的,例如,如果你有一个
公司拥有
员工,那么你也可以说你有一个
员工在
公司工作。在这种情况下,您也会有一个循环依赖关系,然后您可以使用上述方法。

Fair point。当我意识到我有一个循环依赖性时,我想到的第一件事就是我需要重新思考我的设计。我愿意相信,我有一个这样的案例,这是真正需要的。要么这样,要么我需要重新编写大量代码。;-)如果可以拆分它,并且这样做后仍然有意义,那么我认为您应该尽量避免循环依赖。