Dojo cyclic dependency using require

家住魔仙堡 提交于 2019-12-25 16:38:10

问题


I'm using dojo and these are my modules -

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

Now, I'm trying to make

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

But the code fails in ModuleD when it tries to instantiate ModuleB as new ModuleB () with TypeError: ModuleB is not a constructor. I see that ModuleB is just an object and not a function in ModuleD when it is trying to instantiate it. So I know why I get the error. I also realize this is probably because of cyclic dependency and that's the reason ModuleB is not loaded in ModuleD.

I was able to work around this by removing ModuleB from the requires list in the define(...) of ModuleD and instead load it using require() just before it is instantiated. This works.

My Question - Is this the right way of doing something that involves cyclic dependency of modules or is there a better/different way that is recommended?

Thanks,


回答1:


Requiring "on the fly" instead of doing it a define time is the proper approach for circular dependencies.
This is explained here: 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")

Important: At build time, you will have to specify in the build profile all components you had to require on the fly. Otherwise they will not be included in the list of files to build.




回答2:


Even though RequireJS has a proper workaround for circular dependencies like this:

//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)

Using circular dependencies often* means that you have a design that should be improved. Having 2 modules that depend on each other means that you have a highly coupled design, which should ring a bell in every developers brains. Read this for more information: https://softwareengineering.stackexchange.com/questions/11856/whats-wrong-with-circular-references

The proper solution would be that if A depends on B and B depends on A, is that all code that B uses from A is separated in a different module, which we call C. We can then decouple the modules like this:

  • A depends on B
  • A depends on C
  • B depends on C

And there you have it, you have decoupled your code by using an intermediator.


* Cyclic dependencies are not always bad though, for example, if you have a Company that has Employee's, then you could also say that you have an Employee that works within a Company. In this case you would have a circular dependency as well, and then you can use the approach described above.



来源:https://stackoverflow.com/questions/32045101/dojo-cyclic-dependency-using-require

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!