Un modo elegante per rilevare la fine di una ricerca di file ricorsiva asincrona?

0

Data una subroutine ricorsiva in ambiente a thread singolo che avvia numerose operazioni di I / O asincrone e registra le funzioni di callback per ognuna di esse. Questi callback verranno richiamati al completamento delle operazioni.

Quali metodi sono consigliati per rilevare quando tutte le operazioni di I / O sono terminate, in altre parole tutte le richiamate sono state richiamate.

Poiché il codice viene eseguito su un singolo thread, la soluzione più primitiva sarebbe inizializzare una variabile contatore su 0 e incrementare questo contatore prima di ogni operazione di I / O e decrementarlo alla coda delle funzioni di callback. Si possono usare eventi o azioni (come in elm), tuttavia quella soluzione sarebbe molto simile.

Una possibile ottimizzazione: se più operazioni di I / O concatenate insieme (quindi una sola operazione I / O viene avviata nell'altra funzione di callback delle operazioni di I / O), allora sarebbe sufficiente incrementare il contatore all'inizio della catena e del decremento alla fine della catena, Tuttavia, se si verifica il caso in cui più operazioni di I / O vengono avviate in una funzione di callback, allora tutto il ramo deve essere gestito come una catena diversa.

C'è un modo più elegante di gestirlo?

    
posta atevm 26.12.2017 - 12:07
fonte

1 risposta

3

La ricerca di file ricorsiva è simile a camminare su una struttura ad albero . Puoi andare in profondità prima o in ampiezza, sai che hai attraversato l'intero albero quando lo stack / coda che stai utilizzando per gli elementi in sospeso è vuoto. MA Con le API asincrone, come quella di nodejs, la ricorsione è un po 'complicata rispetto al semplice richiamo della funzione.

Ho intenzione di dare un'idea approssimativa:

  1. Definire uno stack per le directory da cercare, aggiungere la directory di avvio / root ad esso.

  2. Definisce una funzione che accetta un percorso di directory e restituisce un flusso leggibile. Questo stream emette ogni directory / file figlio trovato, completo di statistiche.

  3. Prendi / apri una directory dalla # 1 e convertila in streaming usando # 2.

  4. Sul flusso dal # 3, iscriviti a data eventi e se una directory, aggiungi / spingila al # 1. Invia anche i dati a qualunque cosa stia consumando i risultati della ricerca.

  5. Sul flusso dal numero 3, iscriviti all'evento end e vai al # 3.

  6. Quando vai al # 3 e scopri che non c'è nient'altro da far apparire da # 1, la ricerca è completata.

In sostanza, ogni pass è in attesa di elencare e dichiarare i file di 1 directory, prima del passaggio successivo.

    
risposta data 26.12.2017 - 15:02
fonte