Hasta ahora hemos conseguido patinar por uno de los aspectos más desafiantes del nodo, clasificando las secuelas de una operación de sincronización. En las operaciones sincrónicas, todos los datos se devuelven en el orden en que se recuperaron.

Leccion-9 learnyounode Lección 9 - Sincronización de malabares

En el nodo, todos los datos se devuelven en el orden en que se han completado las operaciones de recuperación. Digamos que está obteniendo los datos de cinco archivos y asignando esos datos a una matriz. El primer archivo es de 5 mb, y el último de 20 kb. El resto está en algún punto intermedio. El primer valor en la matriz terminará siendo los datos del archivo más pequeño, en lugar del primer archivo, a menos que tome medidas para asegurarse de que los datos se almacenen en el orden correcto.

Este es realmente el problema que me llevó a los tutoriales de learnyounode. Estaba trabajando en una aplicación de pdf a texto. Mi programa convierte cada página de un pdf en imágenes png, y luego utiliza el reconocimiento óptico de caracteres para convertir la imagen en texto. Después de eso, el texto se agrega a un archivo de texto. Desafortunadamente, las páginas que se añadieron al archivo no estaban en orden porque algunas imágenes eran más grandes que otras y necesitaban más tiempo para procesarlas.

La solución para manejar este lío es contar las llamadas de vuelta. Las llamadas de retorno son la forma en que su código le permitirá al siguiente bloque de código saber que ha terminado con su trabajo. Imagine que usted es el contratista general que coordina la terminación de varias casas. Cada vez que el pintor termina, te llama para avisarte. Usted lleva un registro de esto para que los chicos de recorte y acabado sepan que está ahí para hacer su trabajo en el orden correcto. Imagínate lo decepcionado que estarías si el pintor pintara sobre el adorno de madera dura que habías instalado. Probablemente tan decepcionado como yo cuando descubrí que las páginas de mis pdfs que habían sido convertidos a texto no estaban en orden.

Solución oficial

var http = require(‘http’)
var bl = require(‘bl’)
var results = []
var count = 0
 
function printResults () {
  for (var i = 0; i < 3; i++)
    console.log(results[i])
}
 
function httpGet (index) {
  http.get(process.argv[2 + index], function (response) {
    response.pipe(bl(function (err, data) {
      if (err)
        return console.error(err)
 
      results[index] = data.toString()
      count++
 
      if (count == 3)
        printResults()
    }))
  })
}
 
for (var i = 0; i < 3; i++)
  httpGet(i)

La solución oficial divide esta tarea en dos funciones que asignan e iteran a través de los valores de la matriz resultados'. La función printResults se utiliza para iterar valores en 'results' y registrar los valores en la consola. Si no lo has notado, el bucle for es secuencial. Los resultados[i] no pueden ser registrados en la consola a menos que su valor sea mayor que el valor anterior iterado. Puesto que el iterador 'i' comienza en cero, el primer valor que se puede registrar en la consola son los resultados[0]. El valor del iterador sólo se incrementa en uno cada vez que se ejecuta el bucle, por lo que el único resultado posible es que la siguiente pasada sea el iterador más uno. Esto es importante porque ahora sabemos que nuestros datos necesitan ser agregados a la matriz 'resultados' en el orden correcto. También vale la pena mencionar que el uso de una sentencia 'for in' debería evitarse en este escenario porque un buclefor in’ no devuelve necesariamente los resultados en el orden en que se almacenan en una matriz.

La segunda función utilizada en la solución oficial es httpGet. Esta función acepta un índice como argumento, que se utiliza cuando se llama la función al final del programa. Dentro de httpGet se utiliza el método http.get() del módulo central. Las urls que se solicitan son pasadas como el primer argumento por el valor de llamada de la propiedad process.argv. Tenga en cuenta que el valor del argumento index se añade al índice del array process.argv para pasar múltiples urls introducidas en la línea de comandos de esta función.

El segundo argumento pasado a http.get() es una función de devolución de llamada que acepta la respuesta como argumento. Dentro de la función callback, el método response.pip() se utiliza para canalizar el cuerpo de la respuesta al método bl() desde el módulo `bl’ introducido en la lección anterior.

El método bl() acepta una función de devolución de llamada como argumento, que acepta errores y datos como argumentos. Dentro de la devolución de llamada, si se encuentra un error, se registra en la consola. Además, el valor de los resultados en el índice pasado a httpGet (‘results[index’) se asigna a los datos de la llamada de retorno.

Los datos se convierten en una cadena con el método.toString(). Cada vez que se ejecuta nuestra llamada de retorno dentro del método bl(), el valor de la variable de conteo se incrementa en 1. Si el valor de conteo es igual a 3 para las tres urls que se pasan como argumentos a este programa, se llama a la función printResults.

Finalmente, al final del programa, se utiliza un bucle para iterar a través de valores inferiores a 3 para asignar el índice apropiado a la variable i, que se pasa a httpGet().

El bucle for aquí se usa para iterar a través de cada argumento de la línea de comandos en el orden correcto.

Entonces, ¿dónde ocurre la magia para asegurar que los resultados se registran en la consola en el orden correcto? Comienza con el bucle for al final del programa que itera a través de los argumentos de la línea de comandos en el orden correcto, y pasa el valor del iterador a la función httpGet. Esto asegura que los datos se asignen a la matriz de «resultados» en el orden correcto. Finalmente, el bucle for en la función printResults asegura que los resultados se registren en la consola en el orden correcto.

Reader Interactions

Deja un comentario

Tu dirección de correo electrónico no será publicada.

About David Moya

Apasionado de la Seguridad Informática, aprendiendo en todo momento y profundizando en el mundo web y en el posicionamiento en buscadores.

Share This