Me topé con esta página mientras intentaba resolver un problema en NodeJS: reensamblaje de fragmentos de archivos. Básicamente: tengo una variedad de nombres de archivo. Necesito agregar todos esos archivos, en el orden correcto, para crear un archivo grande. Debo hacer esto asincrónicamente.
El módulo 'fs' de Node proporciona appendFileSync pero no quise bloquear el servidor durante esta operación. Quería usar el módulo fs.promises y encontrar una manera de encadenar todo esto. Los ejemplos en esta página no funcionaron para mí porque realmente necesitaba dos operaciones: fsPromises.read () para leer en el fragmento de archivo y fsPromises.appendFile () para concatenar con el archivo de destino. Tal vez si fuera mejor con javascript podría haber hecho que las respuestas anteriores funcionen para mí. ;-)
Me topé con esto ...
https://css-tricks.com/why-using-reduce-to-sequentially-resolve-promises-works/
... y pude hackear juntos una solución de trabajo.
TLDR:
/**
* sequentially append a list of files into a specified destination file
*/
exports.append_files = function (destinationFile, arrayOfFilenames) {
return arrayOfFilenames.reduce((previousPromise, currentFile) => {
return previousPromise.then(() => {
return fsPromises.readFile(currentFile).then(fileContents => {
return fsPromises.appendFile(destinationFile, fileContents);
});
});
}, Promise.resolve());
};
Y aquí hay una prueba de unidad de jazmín para ello:
const fsPromises = require('fs').promises;
const fsUtils = require( ... );
const TEMPDIR = 'temp';
describe("test append_files", function() {
it('append_files should work', async function(done) {
try {
// setup: create some files
await fsPromises.mkdir(TEMPDIR);
await fsPromises.writeFile(path.join(TEMPDIR, '1'), 'one');
await fsPromises.writeFile(path.join(TEMPDIR, '2'), 'two');
await fsPromises.writeFile(path.join(TEMPDIR, '3'), 'three');
await fsPromises.writeFile(path.join(TEMPDIR, '4'), 'four');
await fsPromises.writeFile(path.join(TEMPDIR, '5'), 'five');
const filenameArray = [];
for (var i=1; i < 6; i++) {
filenameArray.push(path.join(TEMPDIR, i.toString()));
}
const DESTFILE = path.join(TEMPDIR, 'final');
await fsUtils.append_files(DESTFILE, filenameArray);
// confirm "final" file exists
const fsStat = await fsPromises.stat(DESTFILE);
expect(fsStat.isFile()).toBeTruthy();
// confirm content of the "final" file
const expectedContent = new Buffer('onetwothreefourfive', 'utf8');
var fileContents = await fsPromises.readFile(DESTFILE);
expect(fileContents).toEqual(expectedContent);
done();
}
catch (err) {
fail(err);
}
finally {
}
});
});
Espero que esto ayude a alguien.