promesas array all javascript node.js asynchronous fs bluebird

javascript - array - Promesas con fs y bluebird.



promise all (1)

Actualmente estoy aprendiendo a usar promesas en nodejs

así que mi primer desafío fue listar los archivos en un directorio y luego obtener el contenido de cada uno de los dos pasos usando funciones asíncronas. Se me ocurrió la siguiente solución, pero tengo la sensación de que esta no es la forma más elegante de hacerlo, especialmente en la primera parte en la que estoy "convirtiendo" los métodos asíncronos en promesas

// purpose is to get the contents of all files in a directory // using the asynchronous methods fs.readdir() and fs.readFile() // and chaining them via Promises using the bluebird promise library [1] // [1] https://github.com/petkaantonov/bluebird var Promise = require("bluebird"); var fs = require("fs"); var directory = "templates" // turn fs.readdir() into a Promise var getFiles = function(name) { var promise = Promise.pending(); fs.readdir(directory, function(err, list) { promise.fulfill(list) }) return promise.promise; } // turn fs.readFile() into a Promise var getContents = function(filename) { var promise = Promise.pending(); fs.readFile(directory + "/" + filename, "utf8", function(err, content) { promise.fulfill(content) }) return promise.promise }

Ahora encadena ambas promesas:

getFiles() // returns Promise for directory listing .then(function(list) { console.log("We got " + list) console.log("Now reading those files/n") // took me a while until i figured this out: var listOfPromises = list.map(getContents) return Promise.all(listOfPromises) }) .then(function(content) { console.log("so this is what we got: ", content) })

Como escribí anteriormente, devuelve el resultado deseado, pero estoy bastante seguro de que hay una manera más elegante de hacerlo.


El código se puede hacer más corto usando promisificación genérica y el método .map :

var Promise = require("bluebird"); var fs = Promise.promisifyAll(require("fs")); //This is most convenient way if it works for you var directory = "templates"; var getFiles = function () { return fs.readdirAsync(directory); }; var getContent = function (filename) { return fs.readFileAsync(directory + "/" + filename, "utf8"); }; getFiles().map(function (filename) { return getContent(filename); }).then(function (content) { console.log("so this is what we got: ", content) });

De hecho, podría recortar esto aún más, ya que las funciones ya no están reduciendo su peso:

var Promise = require("bluebird"); var fs = Promise.promisifyAll(require("fs")); //This is most convenient way if it works for you var directory = "templates"; fs.readdirAsync(directory).map(function (filename) { return fs.readFileAsync(directory + "/" + filename, "utf8"); }).then(function (content) { console.log("so this is what we got: ", content) });

.map debe ser su método de pan y mantequilla cuando trabaje con colecciones: es realmente poderoso, ya que funciona para cualquier cosa, desde una promesa para una serie de promesas que se mapea hasta nuevas promesas para cualquier combinación de valores directos intermedios.