Große Frage.
Ich denke, Sie können ein paar Dinge tun, um diese Abfrage zu optimieren.
Zuerst können wir die map
Opertors gefolgt von .flatMap(file => file)
zu nur einer einzigen FlatMap ändern. Kleine Verbesserung, aber wird weniger Code ausführen.
const file$ = filesInDir(`${prefix}/${dir}`)
.flatMap(file => file)
.filter(file => !file.startsWith('.'))
const isDir$ = file$
.flatMap(file => statFile(`${prefix}/${dir}/${file}`))
.map(file => file.isDirectory())
return file$
.zip(isDir$, (file, isDir) => {return {file, isDir}})
.flatMap(f => {
if (f.isDir) {
return listFiles(prefix, `${dir}/${f.file}`)
}
return Rx.Observable.return(`${dir}/${f.file}`)
})
Die Hauptverbesserung ist, wo ich glaube, dass Sie tatsächlich das Dateisystem zweimal schlagen. Die beobachtbare Sequenz filesInDir
ist keine Hot/Cached-Sequenz. Wenn ja, würde das rekursive Gehen des Verzeichnisbaums nicht funktionieren. In diesem Sinne rufen Sie es einmal, um alle Dateien zu erhalten, und dann rufen Sie es erneut, um die isDirectory
Prüfung zu tun. Dies führt sowohl zu einem möglichen Leistungsaufwand als auch zu einem Fehler. Sie gehen davon aus, dass die Reihenfolge der zurückgegebenen Dateien immer der gleichen Reihenfolge entspricht, wenn Sie auf die Festplatte klicken. Auch wenn wir für eine Sekunde ignorieren, ist diese Festplatte veränderbar und könnte unter Ihnen ändern. Sie können in einer asynchronen Welt garantieren, dass die Sequenzen in der gleichen Reihenfolge zurückgegeben werden. Auf meinem Computer (Windows 10) wird die Reihenfolge meistens in der gleichen Reihenfolge zurückgegeben. Jedoch mit einem tief genug Baum (z. B. von _C: _) Ich traf jedes Mal eine Diskrepanz.
Wie auch immer, die Performance-Korrektur ist auch der Bugfix. Anstatt jedes Mal erneut aus dem Dateisystem zu lesen, können wir es einmal tun. Verschieben den statFile()
Anruf in ein flatMap
, die auch das Ergebnis Karten mit der Schließung der zu statFile
const listFiles = (prefix, dir) => {
return file$ = filesInDir(`${prefix}/${dir}`)
.flatMap(file => file)
.filter(file => !file.startsWith('.'))
.flatMap(file => statFile(`${prefix}/${dir}/${file}`)
.map(sf => {return {file, isDir: sf.isDirectory()}}))
.flatMap(f => {
if (f.isDir) {
return listFiles(prefix, `${dir}/${f.file}`)
}
return Rx.Observable.return(`${dir}/${f.file}`)
})
}
bestand Datei versucht Dies hat auch den Vorteil, die Zip
Klausel zu entfernen, weil wir nicht mehr mit zwei Sequenzen arbeiten .