2016-06-15 14 views
14

Ich habe ein For-Loop-Array von Versprechen, also habe ich Promise.all verwendet, um durch sie zu gehen und dann danach angerufen.Wie warte ich darauf, dass ein Strom die Verrohrung beendet? (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 und promise3 sind einige HTTP-Anfragen, und wenn einer von ihnen ein application/pdf, dann in einen Stream Ich schreibe es und analysieren den Text aus ihm heraus. Dieser Code führt jedoch die nächste Iteration aus, bevor der Test aus der PDF-Datei analysiert wird. Gibt es eine Möglichkeit, den Code warten zu lassen, bis das Piping an den Stream und das Extrahieren abgeschlossen sind, bevor Sie mit der nächsten Iteration fortfahren?

Antwort

0

Sie können den else-Teil in eine selbst aufgerufene Funktion schreiben. So dass der Umgang mit Strom parallel

(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) 

passieren wird Else können Sie den Streaming-Teil als Teil der ursprünglichen/Einzel Versprechen selbst behandeln.

Ab sofort erstellen Sie das Versprechen und fügen es dem Array hinzu, anstatt dass Sie versprechen, dann das Array (das ist auch ein Versprechen). Und innerhalb des Handlers, um dann deine Streaming-Sachen zu machen.

+0

Dies endet nicht den Strom vor der nächsten Iteration. Ich bekomme immer noch das Versprechen3 wird aufgerufen, bevor Promise2 das Schreiben in den Stream beendet. – user3835653

+0

Es wartet nicht, aber wenn die nächste Iteration in for-Schleife passiert, überschreibt es nicht den Strom von vorherigen und alles funktioniert parallel – Oxi

+0

Was, wenn ich diesen Strom nach der For-Schleife verwenden wollte? Wie verwende ich hier Versprechungen um das zu tun? – user3835653

7

Etwas wie das Folgende würde auch funktionieren. Ich benutze dieses Muster ziemlich oft:

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(); 

oder den Handler an einen Controller brechen und Promisified Handler:

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()