我正在使用dojo,这些是我的模块 -
'myview/ModuleA' --requires--> 'myview/ModuleB'
'myview/ModuleB' --requires--> 'myview/ModuleC'
'myview/ModuleC' --requires--> 'myview/ModuleD'
现在,我正试图制作
'myview/ModuleD' --requires--> 'myview/ModuleB'
但是在尝试使用ModuleB
将new ModuleB ()
实例化为TypeError: ModuleB is not a constructor
时,代码在ModuleD中失败。
我在ModuleB
尝试实例化它时,object
只是function
而不是ModuleD
。所以我知道为什么我会收到错误。我也意识到这可能是因为循环依赖,而ModuleB
中没有加载ModuleD
的原因。
我可以通过从ModuleB
define(...)
中的需求列表中删除ModuleD
来解决此问题,而是在实例化之前使用require()
加载它。这很有效。
我的问题 - 这是做某些涉及模块循环依赖的事情的正确方法,还是建议采用更好/不同的方式?
谢谢,
答案 0 :(得分:1)
要求“动态”而不是define
时间,这是循环依赖的正确方法。
这在此解释:http://requirejs.org/docs/api.html#circular
如果你定义一个循环依赖(“a”需要“b”而“b”需要“a”),那么在这种情况下,当调用“b”的模块函数时,它将获得一个未定义的值“一个”。 “b”可以在使用require()方法定义模块后稍后获取“a”(确保将require指定为依赖项,以便使用正确的上下文查找“a”)
重要提示:在构建时,您必须在构建配置文件中指定您必须动态需要的所有组件。否则,它们将不会包含在要构建的文件列表中。
答案 1 :(得分:1)
尽管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();
}
}
);
( Source )
使用循环依赖经常* 意味着您有一个应该改进的设计。拥有2个彼此依赖的模块意味着您拥有高度耦合的设计,应该在每个开发人员的大脑中敲响钟声。阅读本文以获取更多信息:https://softwareengineering.stackexchange.com/questions/11856/whats-wrong-with-circular-references
正确的解决方案是,如果A依赖于B而B依赖于A,那么B使用的所有代码都是在不同的模块中分离的,我们称之为C.我们可以将模块解耦为:
你有它,你已经通过使用中介来解耦你的代码。
* 循环依赖并不总是很糟糕,例如,如果你的Company
有Employee
,那么你也可以说您有Employee
在Company
内有效。在这种情况下,您也会有循环依赖关系,然后您可以使用上述方法。