Requerir devuelve un objeto vacío


125

Tengo una carpeta que tiene index.js y un par de modelos (clases) index.js

module.exports = {
   Book : require('./book'),
   Author : require('./author')
}

book.js

var Author = require('./author')
var Book = models.ActiveRecord.extend({
    schema : {
        belongsTo : {
            author : Author
        }
    }
})
module.exports = Book

author.js

var Book = require('./book')
var Author = models.ActiveRecord.extend({
    schema : {
        hasMany : {
            author : Book
        }
    }
})

module.exports = Author

¡El problema es que la clase de Autor no parece encontrar el Libro! Es solo un objeto vacío. Sin embargo, si cambio las exportaciones en index.js, colocando Libro después de Autor, funciona, pero luego el otro modelo deja de funcionar.

No quiero hacer ningún truco para que funcione.


44
Author.js necesita Book.js para ejecutarse, y Book.js necesita Author.js para ejecutarse. Eliminar la dependencia circular.
— Philipp Gayret

1
¿Qué objeto de ActiveRecord es ese? ¿De dónde es?
— BT

Respuestas:


207

Esto se debe a que tiene una dependencia circular. Node.js maneja esto de una manera muy específica:

  1. El primer módulo se carga y se ejecuta (en este caso book.js). Se book.jscargará y ejecutará el segundo módulo ( author.js) cuando ( book.js) requiera el otro ( author.js)

  2. Cuando el segundo módulo ( author.js) se carga y se ejecuta, ( author.js) requiere el primer módulo ( book.js) pero ( author.js) recibirá un objeto parcialmente lleno ; sin embargo, muchas cosas se configuraron en las exportaciones en book.js antes de que se requiera author.js estar en ese objeto

  3. Una vez que book.jsse haya ejecutado completamente, el objeto author.jsobtenido require('./book')será el book.jsobjeto de módulo completo

Para obtener más información, aquí están los documentos: http://nodejs.org/api/modules.html

Si es posible agregar dinámicamente ese esquema a uno de esos objetos ActiveRecord, esa es una forma de resolver esto. Esto es realmente una situación complicada. De hecho, incluso sin el sistema de módulos, esto podría causarle problemas. Si coloca todo este código en un archivo, ¿cómo lo haría funcionar?


1
Sé que no deberías poner todo en un archivo, pero estoy diciendo que solo experimentes así. Mi punto es que no es el sistema de módulos de node.js el que está causando el problema aquí, es el código en sí.
— BT

Y de hecho, Java tiene los mismos problemas con las dependencias circulares: es un problema que cualquier lenguaje puede tener. Si todo lo que necesita es una referencia a su socio de dependencia circular, javascript puede hacerlo tan fácilmente como java. Sin embargo, aquí, está intentando usar el objeto antes de que se haya creado (en la extensión)
— BT

Sí, en realidad ahora lo entendí. Nunca me vino a la mente. Entonces, supongo que solo hay una forma: agregarlo dinámicamente. O pasar un nombre de modelo como una cadena. ¡Gracias por su respuesta!
— user3677173

18
Recomiendo mucho a Madge para depurar este tipo de problemas en casos más complejos (es decir, con más archivos). Una vez instalado, puede usarlo madge -c <app entry point>para detectar cualquier dependencia circular.
— schu34

77
Gracias. Es bastante doloroso que ni siquiera arroje un error, sino que solo devuelve un objeto vacío.
— Robert Oschler
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.