Come la risposta di @ Bergi, ma con una differenza.
Promise.all
rifiuta tutte le promesse se uno viene rifiutato.
Quindi, utilizzare una ricorsione.
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()
PS
readFilesQueue
è al di fuori della printFiles
causa dell'effetto collaterale * introdotto da console.log
, è meglio deridere, testare o spiare, quindi non è bello avere una funzione che ritorni il contenuto (sidenote).
Pertanto, il codice può essere semplicemente progettato in base a ciò: tre funzioni separate che sono "pure" ** e non introducono effetti collaterali, elaborano l'intero elenco e possono essere facilmente modificate per gestire casi non riusciti.
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)
Modifica futura / stato attuale
Il nodo supporta l'attesa di alto livello (questo non ha ancora un plugin, non lo avrà e può essere abilitato tramite flag di armonia), è bello ma non risolve un problema (strategicamente lavoro solo su versioni LTS). Come ottenere i file?
Usando la composizione. Dato il codice, mi fa sentire che questo è all'interno di un modulo, quindi dovrebbe avere una funzione per farlo. Altrimenti, dovresti usare un IIFE per avvolgere il codice del ruolo in una funzione asincrona creando un modulo semplice che fa tutto per te, oppure puoi andare nel modo giusto, c'è composizione.
// more complex version with IIFE to a single module
(async (files) => readFiles(await files())(getFilesPath)
Si noti che il nome della variabile cambia a causa della semantica. Si passa un functor (una funzione che può essere invocata da un'altra funzione) e riceve un puntatore in memoria che contiene il blocco logico iniziale dell'applicazione.
Ma se non è un modulo e devi esportare la logica?
Avvolgi le funzioni in una funzione asincrona.
export const readFilesQueue = async () => {
// ... to code goes here
}
O cambia i nomi delle variabili, qualunque cosa ...
*
per effetto collaterale menana qualsiasi effetto colecale dell'applicazione che può cambiare lo statuto / comportamento o introdurre bug nell'applicazione, come IO.
**
da "puro", è in apostrofo poiché le funzioni non sono pure e il codice può essere convertito in una versione pura, quando non c'è l'output della console, ma solo manipolazioni dei dati.
A parte questo, per essere puri, dovrai lavorare con monadi che gestiscono l'effetto collaterale, che sono soggetti a errori e trattano quell'errore separatamente dall'applicazione.
for ... of ...
funziona?