2011-06-09 10 views
6

En el node.js documentation regarding module caching, se hace la siguiente declaración:Node.js: almacenamiento en caché de módulos, objetos parcialmente finalizados y dependencias cíclicas?

Varias llamadas a require ('foo') no puede hacer que el código del módulo que se ejecuta varias veces. Esta es una característica importante. Con él, "parcialmente hecho" se pueden devolver objetos, permitiendo así que las dependencias transitivas se carguen aunque ocasionen ciclos.

Estoy un poco confundido acerca de la última frase. ¿Qué es un objeto "parcialmente hecho"? ¿Cómo se relaciona esto con permitir (o evitar) dependencias cíclicas?

Respuesta

5

Si require un paquete desde un archivo, y que hace que un archivo en ese paquete a require el archivo que causó la inicial require entonces usted tiene una dependencia cíclica. De forma predeterminada, sería simplemente vaya en círculos. Para evitar esto, se puede mantener un marcador donde se inició el require original, de modo que la próxima vez que ese archivo sea require se iniciará desde ese punto en lugar de desde el principio. No es perfecto, pero en el caso de cargar un paquete generalmente solo está interesado en las exportaciones, y funciona bien en ese caso.

Hace un tiempo empujé a diff for node-browserify para un método primitivo de exportaciones "parcialmente hechas". Básicamente, cada vez que algo es require 'd se verificará la cantidad de exportaciones. Si hay más exportaciones, significa que el paquete estuvo incompleto la última vez y aún podría procesarse. Si no hay nuevas exportaciones (el recuento nuevo y el anterior son iguales), significa que el paquete está hecho y puede almacenarse en caché para que el código del módulo no se ejecute varias veces. Siendo que está en el navegador, no hay control sobre el flujo de ejecución y, por lo tanto, el código del módulo se repetirá parcialmente (en pasos) hasta que se complete. Mientras que estoy seguro de que Node.js tiene un manejo más elegante.

0

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 
Cuestiones relacionadas