javascript - examples - La dependencia cíclica Dojo requiere
dojo tutorial (2)
Estoy usando dojo y estos son mis módulos -
''myview/ModuleA'' --requires--> ''myview/ModuleB''
''myview/ModuleB'' --requires--> ''myview/ModuleC''
''myview/ModuleC'' --requires--> ''myview/ModuleD''
Ahora, estoy tratando de hacer
''myview/ModuleD'' --requires--> ''myview/ModuleB''
Pero el código falla en ModuleD cuando intenta crear ModuleB
instancia de ModuleB
como new ModuleB ()
con TypeError: ModuleB is not a constructor
. Veo que ModuleB
es solo un object
y no una function
en ModuleD
cuando intenta crear una instancia. Entonces sé por qué me sale el error. También me doy cuenta de que esto es probablemente debido a la dependencia cíclica y esa es la razón por la que ModuleB
no se carga en ModuleD
.
Pude ModuleB
este problema eliminando ModuleB
de la lista de requisitos en la define(...)
de ModuleD
y en su lugar, ModuleD
usando require()
justo antes de que se instanciara. Esto funciona.
Mi pregunta: ¿Es esta la manera correcta de hacer algo que involucra la dependencia cíclica de los módulos o hay una forma mejor / diferente que se recomienda?
Gracias,
Aunque RequireJS tiene una solución adecuada para las dependencias circulares como esta:
//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();
}
}
);
( Fuente )
El uso de dependencias circulares a menudo * significa que tiene un diseño que debe mejorarse. Tener 2 módulos que dependen el uno del otro significa que tienes un diseño altamente acoplado, que debe sonar en todos los cerebros de los desarrolladores. Lea esto para obtener más información: https://softwareengineering.stackexchange.com/questions/11856/whats-wrong-with-circular-references
La solución adecuada sería que si A depende de B y B depende de A, es que todo el código que B usa de A está separado en un módulo diferente, que llamamos C. Entonces podemos desacoplar los módulos como este:
- A depende de B
- A depende de C
- B depende de C
Y ahí lo tienes, has desacoplado tu código usando un intermediario.
* Las dependencias cíclicas no siempre son malas, aunque, por ejemplo, si tiene una Company
que tiene Employee
, entonces también podría decir que tiene un Employee
que trabaja dentro de una Company
. En este caso, también tendría una dependencia circular, y luego puede usar el enfoque descrito anteriormente.
Requerir "sobre la marcha" en lugar de hacerlo un tiempo de define
es el enfoque adecuado para las dependencias circulares.
Esto se explica aquí: http://requirejs.org/docs/api.html#circular
Si define una dependencia circular ("a" necesita "b" y "b" necesita "a"), en este caso cuando se llama a la función de módulo "b", obtendrá un valor indefinido para "a". "b" puede buscar "a" más tarde después de que los módulos se hayan definido utilizando el método require () (asegúrese de especificar require como dependencia para que el contexto correcto se use para buscar "a")
Importante: en el momento de la compilación, deberá especificar en el perfil de compilación todos los componentes que requirió sobre la marcha. De lo contrario, no se incluirán en la lista de archivos para compilar.