如何等待小溪完成pipe道? (的NodeJS)

我有一个承诺的循环数组,所以我用Promise.all来通过它们,然后调用。

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和promise3是一些http请求,如果其中一个是application / pdf,那么我将它写入一个stream,并将其parsing出来。 但是这个代码在parsingtesting之前运行下一个迭代。 有没有办法让代码等待,直到stream和pipe道的提取完成,然后再继续下一个迭代?

Solutions Collecting From Web of "如何等待小溪完成pipe道? (的NodeJS)"

类似下面的东西也可以。 我经常使用这种模式:

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

或将处理程序分解为控制器和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() 

你可以在自调函数中写入else部分。 所以stream的处理将并行进行

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

否则,您可以将stream媒体部分作为原始/个人承诺本身的一部分。

到目前为止,您正在创build承诺并将其添加到数组中,而不是添加promise,然后添加到数组(这也是一个承诺)。 然后在处理程序里面,你做你的stream媒体的东西。

使用bluebird承诺可以访问mapSeries函数,它正是你想要做的:

 const Promise = require('bluebird') let promises = []; promises.push(promise1); promises.push(promise2); promises.push(promise3); Promise.all([promise1, promise2, promise3]) .mapSeries((response) => { if (response.property === something) return 'something' const file = fs.createWriteStream('./hello.pdf'); const stream = response.pipe(file) return new Promise((resolve, reject) => { stream.on('finish', () => { extract(filePath, (err, text) => { if (err) reject(err) else resolve(text) }) }) }) }) .map((text, index) => { arrayOfDocuments[index].text_contents = text }) 

蓝鸟文件