使用 require 的 Dojo 循环依赖
Dojo cyclic dependency using require
我正在使用 dojo,这些是我的模块 -
'myview/ModuleA' --requires--> 'myview/ModuleB'
'myview/ModuleB' --requires--> 'myview/ModuleC'
'myview/ModuleC' --requires--> 'myview/ModuleD'
现在,我正在尝试
'myview/ModuleD' --requires--> 'myview/ModuleB'
但是当 ModuleD 尝试将 ModuleB
实例化为 new ModuleB ()
和 TypeError: ModuleB is not a constructor
时,代码在 ModuleD 中失败。
我看到 ModuleB
只是一个 object
而不是 ModuleD
中的 function
当它试图实例化它时。所以我知道为什么我会收到错误。我也意识到这可能是因为循环依赖,这就是 ModuleB
未加载到 ModuleD
.
的原因
我能够通过从 ModuleD
的 define(...)
中的需求列表中删除 ModuleB
来解决这个问题,而是在它被加载之前使用 require()
加载它实例化。这行得通。
我的问题 - 这是执行涉及模块循环依赖的正确方法还是有推荐的 better/different 方法?
谢谢,
要求 "on the fly" 而不是 define
时间是循环依赖的正确方法。
这在这里解释:http://requirejs.org/docs/api.html#circular
If you define a circular dependency ("a" needs "b" and "b" needs "a"), then in this case when "b"'s module function is called, it will get an undefined value for "a". "b" can fetch "a" later after modules have been defined by using the require() method (be sure to specify require as a dependency so the right context is used to look up "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();
}
}
);
(Source)
经常使用循环依赖*意味着您的设计需要改进。拥有 2 个相互依赖的模块意味着您拥有高度耦合的设计,这应该在每个开发人员的大脑中敲响警钟。阅读此内容以获取更多信息:https://softwareengineering.stackexchange.com/questions/11856/whats-wrong-with-circular-references
正确的解决方案是,如果 A 依赖于 B 而 B 依赖于 A,那么 B 从 A 使用的所有代码都分离在一个不同的模块中,我们称之为 C。然后我们可以解耦模块,例如这个:
- A依赖B
- A依赖C
- B依赖C
好了,您已经通过使用中间体解耦了代码。
* 循环依赖并不总是坏的,例如,如果你有一个有 Employee
的 Company
,那么你也可以假设您有一个在 Company
中工作的 Employee
。在这种情况下你也会有一个循环依赖,然后你可以使用上面描述的方法。
我正在使用 dojo,这些是我的模块 -
'myview/ModuleA' --requires--> 'myview/ModuleB'
'myview/ModuleB' --requires--> 'myview/ModuleC'
'myview/ModuleC' --requires--> 'myview/ModuleD'
现在,我正在尝试
'myview/ModuleD' --requires--> 'myview/ModuleB'
但是当 ModuleD 尝试将 ModuleB
实例化为 new ModuleB ()
和 TypeError: ModuleB is not a constructor
时,代码在 ModuleD 中失败。
我看到 ModuleB
只是一个 object
而不是 ModuleD
中的 function
当它试图实例化它时。所以我知道为什么我会收到错误。我也意识到这可能是因为循环依赖,这就是 ModuleB
未加载到 ModuleD
.
我能够通过从 ModuleD
的 define(...)
中的需求列表中删除 ModuleB
来解决这个问题,而是在它被加载之前使用 require()
加载它实例化。这行得通。
我的问题 - 这是执行涉及模块循环依赖的正确方法还是有推荐的 better/different 方法?
谢谢,
要求 "on the fly" 而不是 define
时间是循环依赖的正确方法。
这在这里解释:http://requirejs.org/docs/api.html#circular
If you define a circular dependency ("a" needs "b" and "b" needs "a"), then in this case when "b"'s module function is called, it will get an undefined value for "a". "b" can fetch "a" later after modules have been defined by using the require() method (be sure to specify require as a dependency so the right context is used to look up "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();
}
}
);
(Source)
经常使用循环依赖*意味着您的设计需要改进。拥有 2 个相互依赖的模块意味着您拥有高度耦合的设计,这应该在每个开发人员的大脑中敲响警钟。阅读此内容以获取更多信息:https://softwareengineering.stackexchange.com/questions/11856/whats-wrong-with-circular-references
正确的解决方案是,如果 A 依赖于 B 而 B 依赖于 A,那么 B 从 A 使用的所有代码都分离在一个不同的模块中,我们称之为 C。然后我们可以解耦模块,例如这个:
- A依赖B
- A依赖C
- B依赖C
好了,您已经通过使用中间体解耦了代码。
* 循环依赖并不总是坏的,例如,如果你有一个有 Employee
的 Company
,那么你也可以假设您有一个在 Company
中工作的 Employee
。在这种情况下你也会有一个循环依赖,然后你可以使用上面描述的方法。