web-dev-qa-db-ja.com

ストリームがパイピングを完了するのを待つ方法は? (Nodejs)

私は約束のforループ配列を持っているので、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要求であり、そのうちの1つがapplication/pdfである場合、ストリームに書き込み、テキストを解析します。ただし、このコードは、pdfからテストを解析する前に次の反復を実行します。次の反復に進む前に、ストリームへのパイピングと抽出が完了するまでコードを待機させる方法はありますか?

26
PraneethVT

次のようなものも動作します。私はこのパターンをかなり頻繁に使用します。

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

Async/awaitがなければ、非常に厄介です。 async/awaitでは、次のようにします。

Promise.all(promises).then(async (responses) => {
  for (...) {
    await new Promise(fulfill => stream.on("finish", fulfill));
    //extract the text out of the PDF
  }
})
9
Hai Phan