2011-05-13 24 views
5

Estoy construyendo un sistema en Node.js que se supone que debe encontrar todos los archivos en una matriz de carpetas, registrarlos y luego realizar algún trabajo adicional utilizando esa información.Agregue parámetros adicionales a la función de devolución de llamada

Estoy usando fs.readdir() para obtener todos los archivos de forma sincrónica desde cada una de las carpetas. Mi código es el siguiente:

for(i=0,max=paths.length; i<max; i++) { 
    var path = paths.pop(); 
    console.log("READING PATH: " + path); 
    fs.readdir(path, function(err, files) { handleDir(err, files, path); }); 
} 

El problema es que, dependiendo de la rapidez con la readdir() ejecuta, handleDir() está recibiendo el camino equivocado. Esto sucede porque para cuando se ejecuta la devolución de llamada, el siguiente ciclo ya ha comenzado, lo que significa que la variable de ruta ha cambiado.

Entonces, lo que tengo que hacer es bloquear de alguna manera esa variable de ruta a su función de devolución de llamada específica. No puedo pensar en ninguna buena manera de hacer esto, ¿alguien tiene algunas ideas?

Respuesta

7

No hay alcance de bloque, por lo tanto, use una función para el osciloscopio.

for(var i=0, path, max=paths.length; i<max; i++) { 
    path = paths.pop(); 
    console.log("READING PATH: " + path); 
    handlePath(path); 
} 
function handlePath (path) { 
    fs.readdir(path, onPathRead); 
    function onPathRead (err, files) { 
     handleDir(err, files, path); 
    } 
} 
6

Esta es una de las partes más molestas de JS para mí. Una alternativa para crear una función separada (como demostró @generalhenry) es envolver el código en una función anónima que se ejecuta antes de que cambie la variable de ruta.

for(i=0,max=paths.length; i<max; i++) { 
    var path = paths.pop(); 
    console.log("READING PATH: " + path); 
    fs.readdir(path, 
     (function(p){ 
      return function(err, files) { 
       handleDir(err, files, p); 
      }; 
     })(path); 
    ); 
} 

De cualquier manera, el punto importante es que se inicia el contexto de la función (anónimo o no) antes de que se reasigna el valor de la variable de ruta.

+0

Me gusta esta técnica por su concisión – nicolaskruchten

1

Esto es de hecho una característica molesta de Javascript, hasta el punto de que Coffeescript (que es un lenguaje que se compila a Javascript) tiene una forma específica de manejarlo, el operador do en for. En CoffeeScript su función original sería:

for path in paths 
    fs.readdir path, (err, files) -> handleDir(err, files, path) 

y la solución a su problema sería:

for path in paths 
    do (path) -> 
    fs.readdir path, (err, files) -> handleDir(err, files, path) 
+0

¿Esto simplemente se resume a la misma cosa que las dos respuestas anteriores? – jwegner

+0

Más o menos, sí, solo quería conectar esta (IMO) solución muy elegante y concisa :) – nicolaskruchten

0

que estaba buscando lo mismo y terminar con la solución y aquí se trata de un ejemplo sencillo si alguien quiere pasar por esto

var FA = function(data){ 
    console.log("IN A:"+data) 
    FC(data,"LastName"); 
}; 
var FC = function(data,d2){ 
    console.log("IN C:"+data,d2) 
}; 
var FB = function(data){ 
    console.log("IN B:"+data); 
    FA(data) 
}; 
FB('FirstName') 
Cuestiones relacionadas