Hay un ejemplo agradable y claro en el node.js documentation. Arroja más luz sobre el objeto "parcialmente hecho" y las dependencias cíclicas.
Cuando hay llamadas circulares require(), un módulo puede no haber terminado de ejecutarse cuando se devuelve.
considerar esta situación:
a.js:
console.log('a starting');
exports.done = false;
const b = require('./b.js');
console.log('in a, b.done = %j', b.done);
exports.done = true;
console.log('a done');
b.js:
console.log('b starting');
exports.done = false;
const a = require('./a.js');
console.log('in b, a.done = %j', a.done);
exports.done = true;
console.log('b done');
main.js:
console.log('main starting');
const a = require('./a.js');
const b = require('./b.js');
console.log('in main, a.done=%j, b.done=%j', a.done, b.done);
Cuando main.js cargas a.js, a continuación, a su vez carga a.js b.js. En ese punto, b.js intenta cargar a.js. Para evitar un bucle infinito, se devuelve una copia sin terminar del objeto de exportación a.js al módulo b.js. b.js luego finaliza la carga y su objeto de exportación se proporciona al módulo a.js.
Para cuando main.js ha cargado ambos módulos, ambos están terminados.La salida de este programa sería así:
nodo main.js
main starting
a starting
b starting
in b, a.done = false
b done
in a, b.done = true
a done
in main, a.done=true, b.done=true