使用require的Dojo循环依赖

时间:2015-08-17 07:41:47

标签: javascript dojo

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

'myview/ModuleA' --requires--> 'myview/ModuleB'
'myview/ModuleB' --requires--> 'myview/ModuleC'
'myview/ModuleC' --requires--> 'myview/ModuleD'

现在,我正试图制作

'myview/ModuleD' --requires--> 'myview/ModuleB'

但是在尝试使用ModuleBnew ModuleB ()实例化为TypeError: ModuleB is not a constructor时,代码在ModuleD中失败。 我在ModuleB尝试实例化它时,object只是function而不是ModuleD。所以我知道为什么我会收到错误。我也意识到这可能是因为循环依赖,而ModuleB中没有加载ModuleD的原因。

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

我的问题 - 这是做某些涉及模块循环依赖的事情的正确方法,还是建议采用更好/不同的方式?

谢谢,

2 个答案:

答案 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.我们可以将模块解耦为:

  • A取决于B
  • A取决于C
  • B取决于C

你有它,你已经通过使用中介来解耦你的代码。

* 循环依赖并不总是很糟糕,例如,如果你的CompanyEmployee,那么你也可以说您有EmployeeCompany内有效。在这种情况下,您也会有循环依赖关系,然后您可以使用上述方法。