使用Promise确保文件流已结束

时间:2018-10-02 08:16:01

标签: javascript node.js promise

我从以下两个变量开始

var yearTotal2008 = 0; 
var year2008TallyByPatient = {};

然后通读一个大型csv文件的每一行,从而相应地更新两个变量。这需要一段时间。

const produceChartData = () => {
  inputStream
    .pipe(CsvReadableStream())
    .on('data', function (row) {
      if ((20080101 <= row[3]) && (row[3] <= 20081231)) {
        yearTotal2008 += parseFloat(row[6])
        yearPatientTally(year2008TallyByPatient, row[0], parseFloat(row[6]))
      }
})
    .on('end', function (data) {
      console.log('end of the read')
      console.log('year total claims: ' + yearTotal2008)
      console.log('average claims by patient: ' + averageClaimByPatient(year2008TallyByPatient))
      return;
    })
  }

我想确保流已完成并且所有相关值都已添加到两个变量中。

function resolveGetCall (getCall) {
  return Promise.resolve(getCall)
}

resolveGetCall(produceChartData())
  .then(result => { 
    return Promise.resolve(averageClaimByPatient(year2008TallyByPatient)) 
  })
  .then(result => console.log(result))

输出结果是这样的

NaN
end of the read
year total claims: 125329820
average claims by patient: 2447.70

我一直在寻找其他线程,只是没有点击我做错了什么。

2 个答案:

答案 0 :(得分:2)

您的produceChartData目前未返回任何内容。您需要对其进行转换以返回解析Promise的{​​{1}}。 (仅使用on('end'不会使任何异步操作自动等待)

例如:

Promise.resolve(getCall)

然后,您可以在const produceChartData = () => { return new Promise((resolve) => { inputStream .pipe(CsvReadableStream()) .on('data', function (row) { if ((20080101 <= row[3]) && (row[3] <= 20081231)) { yearTotal2008 += parseFloat(row[6]) yearPatientTally(year2008TallyByPatient, row[0], parseFloat(row[6])) } }) .on('end', function (data) { console.log('end of the read') console.log('year total claims: ' + yearTotal2008) console.log('average claims by patient: ' + averageClaimByPatient(year2008TallyByPatient)) resolve(); }) }); } 的呼叫后直接呼叫then

produceChartData

我看到你在用

produceChartData()
  .then(() => {
    console.log('all done');
  });

如果return Promise.resolve(averageClaimByPatient(year2008TallyByPatient)) 异步运行,那么您也需要将其转换为也返回averageClaimByPatient,就像上面修改了Promise一样。然后,只需produceChartData return

Promise

答案 1 :(得分:2)

要保证工作正常,您需要一个“异步根”,这是一个回调。由于您的函数produceChartData不接受回调也不返回承诺,因此无法使用它。但是它很容易添加:

 const produceChartData = () => new Promise(resolve => { // return a promise and produce a callback
   inputStream
    .pipe(CsvReadableStream())
    .on('data', function (row) {
      if ((20080101 <= row[3]) && (row[3] <= 20081231)) {
        yearTotal2008 += parseFloat(row[6])
        yearPatientTally(year2008TallyByPatient, row[0],  parseFloat(row[6]))
     }
  })
  .on('end', function (data) {
     console.log('end of the read')
     console.log('year total claims: ' + yearTotal2008)
     console.log('average claims by patient: ' + averageClaimByPatient(year2008TallyByPatient))
     resolve({ yearTotal2008, year2008TallyByPatient }); // call back
  })
});

可以用作:

 produceChartData().then(({ yearTotal2008 }) => {
   console.log(yearTotal2008);
 });