2016-06-15 60 views
14

Ho una serie di promemoria per ciclo, quindi ho usato Promise.all per esaminarli e poi richiamarli.Come attendere che un flusso completi le tubazioni? (Nodejs)

let promises = []; 
promises.push(promise1); 
promises.push(promise2); 
promises.push(promise3); 

Promise.all(promises).then((responses) => { 
    for (let i = 0; i < promises.length; i++) { 
    if (promise.property === something) { 
     //do something 
    } else { 
     let file = fs.createWriteStream('./hello.pdf'); 
     let stream = responses[i].pipe(file); 
     /* 
     I WANT THE PIPING AND THE FOLLOWING CODE 
     TO RUN BEFORE NEXT ITERATION OF FOR LOOP 
     */ 
     stream.on('finish',() => { 
     //extract the text out of the pdf 
     extract(filePath, {splitPages: false}, (err, text) => { 
     if (err) { 
      console.log(err); 
     } else { 
      arrayOfDocuments[i].text_contents = text; 
     } 
     }); 
    });  
    } 
} 

promise1, promise2, e promise3 sono alcune richieste http, e se uno di loro è un application/pdf, poi scrivo ad un ruscello e analizzare il testo fuori di esso. Ma questo codice esegue la successiva iterazione prima di analizzare il test dal pdf. C'è un modo per fare in modo che il codice attenda fino a quando le tubazioni verso lo stream e l'estrazione non sono terminate prima di passare alla successiva iterazione?

risposta

0

È possibile scrivere la parte else all'interno di una funzione auto-invocata. In modo che la gestione di flusso avverrà in parallelo

(function(i) { 
    let file = fs.createWriteStream('./hello.pdf'); 
    let stream = responses[i].pipe(file); 
    /* 
    I WANT THE PIPING AND THE FOLLOWING CODE 
    TO RUN BEFORE NEXT ITERATION OF FOR LOOP 
    */ 
    stream.on('finish',() => { 
     //extract the text out of the pdf 
     extract(filePath, {splitPages: false}, (err, text) => { 
     if (err) { 
     console.log(err); 
     } 
     else { 
     arrayOfDocuments[i].text_contents = text; 
     } 
    }); 
    });  
})(i) 

Altrimenti è possibile gestire la parte di streaming come parte della promessa originale/individuo stesso.

A partire da ora si sta creando la promessa e aggiungendola all'array, invece di aggiungere promessa.quindi all'array (che è anche una promessa). E dentro al conduttore per fare le tue cose in streaming.

+0

Questo non termina la torrente prima della prossima iterazione. Ricevo ancora che la promessa3 venga chiamata prima che promise2 termini di scrivere nello stream. – user3835653

+0

Non aspetta, ma quando si verifica la prossima iterazione in ciclo, non sovrascriverà il flusso dal precedente e tutto funzionerà in parallelo – Oxi

+0

E se volessi usare quel flusso dopo aver fatto il ciclo for? Come faccio a usare le promesse qui per farlo? – user3835653

7

Funzionerebbe anche il seguente. Io uso questo modello abbastanza spesso:

let promises = []; 
promises.push(promise1); 
promises.push(promise2); 
promises.push(promise3); 

function doNext(){ 
    if(!promises.length) return; 
    promises.shift().then((resolved) =>{ 
    if(resolved.property === something){ 
     ... 
     doNext(); 
    }else{ 
     let file = fs.createWriteStream('./hello.pdf'); 
     let stream = resolved.pipe(file); 
     stream.on('finish',() =>{ 
     ... 
     doNext(); 
     }); 
    } 

    }) 
} 
doNext(); 

o rompere il gestore per un controller e gestore Promisified:

function streamOrNot(obj){ 
    return new Promise(resolve, reject){ 
    if(obj.property === something){ 
     resolve(); 
     return; 
    } 
    let file = fs.createWriteStream...; 
    stream.on('finish',() =>{ 
     ... 
     resolve(); 
    }); 
    } 
} 

function doNext(){ 
    if(!promises.length) return; 
    return promises.shift().then(streamOrNot).then(doNext); 
} 

doNext()