Diese Antwort verwendet keine blockierenden Funktionen wie readdirSync
oder statSync
. Sie verwendet keine externen Abhängigkeiten und befindet sich nicht in den Tiefen der Rückrufhölle.
Stattdessen verwenden wir moderne JavaScript-Annehmlichkeiten wie Promises und async-await
-Syntax. Und asynchrone Ergebnisse werden parallel und nicht sequenziell verarbeitet -
const { readdir, stat } =
require("fs").promises
const { join } =
require("path")
const dirs = async (path = ".") =>
(await stat(path)).isDirectory()
? Promise
.all
((await readdir(path))
.map(p => dirs(join(path, p)))
)
.then
(results =>
[].concat(path, ...results)
)
: []
Ich werde ein Beispiel-Paket installieren und dann unsere Funktion testen -
$ npm install ramda
$ node
Lassen Sie uns sehen, wie es funktioniert -
> dirs(".").then(console.log, console.error)
[ '.'
, 'node_modules'
, 'node_modules/ramda'
, 'node_modules/ramda/dist'
, 'node_modules/ramda/es'
, 'node_modules/ramda/es/internal'
, 'node_modules/ramda/src'
, 'node_modules/ramda/src/internal'
]
Mit einem verallgemeinerten Modul, Parallel
, können wir die Definition von dirs
vereinfachen -
const Parallel =
require("./Parallel")
const dirs = async (path = ".") =>
(await stat(path)).isDirectory()
? Parallel(readdir(path))
.flatMap(f => dirs(join(path, f)))
.then(results => [path, ...results])
: []
Das oben verwendete Parallel
-Modul war ein Muster, das aus einer Reihe von Funktionen extrahiert wurde, die entworfen wurden, um ein ähnliches Problem zu lösen. Für weitere Erklärungen siehe diese verwandte Q&A.