Digamos que tiene una gran (> 1 GB) CSV de ID de registros:Cómo ejecutar una función asíncrona para cada línea de un archivo muy grande (> 1 GB) en Node.js
655453
4930285
493029
4930301
493031
...
Y para cada id
desea realizar una llamada a la API REST para recuperar los datos del registro, transformarlos localmente e insertarlos en una base de datos local.
¿Cómo se hace eso con Node.js 'Readable Stream
?
Mi pregunta es básicamente esta: ¿cómo se lee un archivo muy grande, línea por línea, se ejecuta una función asíncrona para cada línea, y [opcionalmente] se puede comenzar a leer el archivo desde una línea específica?
A partir de la siguiente pregunta Quora estoy empezando a aprender a usar fs.createReadStream
:
http://www.quora.com/What-is-the-best-way-to-read-a-file-line-by-line-in-node-js
var fs = require('fs');
var lazy = require('lazy');
var stream = fs.createReadStream(path, {
flags: 'r',
encoding: 'utf-8'
});
new lazy(stream).lines.forEach(function(line) {
var id = line.toString();
// pause stream
stream.pause();
// make async API call...
makeAPICall(id, function() {
// then resume to process next id
stream.resume();
});
});
embargo, que pseudocódigo no funciona, debido a que las fuerzas lazy
module a leer todo el archivo (como una secuencia, pero no hay pausa). Entonces, ese enfoque no parece funcionar.
Otra cosa es, me gustaría poder comenzar a procesar este archivo desde una línea específica. La razón de esto es que procesar cada id
(realizar la llamada de la API, limpiar los datos, etc.) puede llevar hasta medio segundo por registro, así que no quiero tener que comenzar desde el principio del archivo cada vez . El enfoque ingenuo que estoy pensando utilizar es capturar el número de línea de la última identificación procesada y guardar eso. Luego, cuando vuelva a analizar el archivo, transmita todos los ID, línea por línea, hasta que encuentre el número de línea que dejó en, y luego haga el negocio makeAPICall
. Otro enfoque ingenuo es escribir archivos pequeños (digamos de 100 ids) y procesar cada archivo de a uno por vez (un conjunto de datos suficientemente pequeño para hacer todo en la memoria sin una secuencia IO). ¿Hay una mejor manera de hacer esto?
puedo ver cómo esto se complica (y donde node-lazy viene en) porque el chunk
en stream.on('data', function(chunk) {});
sólo podrán contener parte de una línea (si el bufferSize es pequeño, cada bloque puede ser de 10 líneas, pero debido a que el id
es longitud variable, solo puede ser 9.5 líneas o lo que sea). Es por eso que me pregunto cuál es el mejor enfoque para la pregunta anterior.
conjetura esto es lo Redis y trabajos en segundo plano son para ... –
empezando a verse prometedora: https://gist.github.com/2947293 –
he publicado una solución a una pregunta similar para analizar una muy grande archivo, utilizando una secuencia, sincrónico. ver: http://stackoverflow.com/questions/16010915/parsing-huge-logfiles-in-node-js-read-in-line-by-line/23695940#23695940 – Gerard