Como la respuesta de @ Bergi, pero con una diferencia.
Promise.all
rechaza todas las promesas si uno es rechazado.
Entonces, usa una recursión.
const readFilesQueue = async (files, index = 0) {
const contents = await fs.readFile(files[index], 'utf8')
console.log(contents)
return files.length <= index
? readFilesQueue(files, ++index)
: files
}
const printFiles async = () => {
const files = await getFilePaths();
const printContents = await readFilesQueue(files)
return printContents
}
printFiles()
PD
readFilesQueue
está fuera de printFiles
causa del efecto secundario * introducido por console.log
, es mejor burlarse, probar o espiar, por lo que no es bueno tener una función que devuelva el contenido (nota al margen).
Por lo tanto, el código puede ser diseñado simplemente por eso: tres funciones separadas que son "puras" ** y no presentan efectos secundarios, procesan la lista completa y pueden modificarse fácilmente para manejar casos fallidos.
const files = await getFilesPath()
const printFile = async (file) => {
const content = await fs.readFile(file, 'utf8')
console.log(content)
}
const readFiles = async = (files, index = 0) => {
await printFile(files[index])
return files.lengh <= index
? readFiles(files, ++index)
: files
}
readFiles(files)
Edición futura / estado actual
Node admite espera de nivel superior (esto aún no tiene un complemento, no lo tendrá y se puede habilitar a través de indicadores de armonía), es genial pero no resuelve un problema (estratégicamente solo trabajo en versiones LTS). ¿Cómo obtener los archivos?
Usando la composición. Dado el código, me causa la sensación de que esto está dentro de un módulo, por lo tanto, debería tener una función para hacerlo. Si no, debe usar un IIFE para envolver el código de rol en una función asíncrona creando un módulo simple que haga todo por usted, o puede ir de la manera correcta, hay, composición.
// more complex version with IIFE to a single module
(async (files) => readFiles(await files())(getFilesPath)
Tenga en cuenta que el nombre de las variables cambia debido a la semántica. Pasa un functor (una función que puede ser invocada por otra función) y recibe un puntero en la memoria que contiene el bloque inicial de lógica de la aplicación.
Pero, si no es un módulo y necesita exportar la lógica?
Envuelva las funciones en una función asíncrona.
export const readFilesQueue = async () => {
// ... to code goes here
}
O cambiar los nombres de las variables, lo que sea ...
*
por efecto secundario significa cualquier efecto colacteral de la aplicación que puede cambiar el estado / comportamiento o introducir errores en la aplicación, como IO.
**
por "puro", está en apóstrofo ya que las funciones no son puras y el código puede converger a una versión pura, cuando no hay salida de consola, solo manipulaciones de datos.
Aparte de esto, para ser puro, necesitará trabajar con mónadas que manejan el efecto secundario, que son propensas a errores, y tratan ese error por separado de la aplicación.
for ... of ...
funciona?