createReadStream等待第一个完成,然后再开始第二个createReadStream

时间:2020-09-13 19:06:01

标签: javascript node.js asynchronous

据我所知,createReadStream是异步的,没有等效的同步方法。这导致我们今天遇到的问题。正如您在我的代码中看到的那样,我有两个createReadStream,第二个依赖于第一个,并且绝对需要运行它才能使stationIds充满所需的值。我的问题是stationIds为空,因此第二个createReadStream根本不执行任何操作,如何以所需的正确方式运行这两个createReadStream?

// Read content of files 
csvDataFiles.forEach(file => {
  const data = []
  fs.createReadStream(directory + file)
  .pipe(csv())
  .on('data', function (row) {
    data.push(row)
  })
  .on('end', function() {
    const object = {}
    let stationId = parseInt(file.substr(0, file.indexOf('.')))
    stationIds.push(stationId)
    object[stationId] = {}
    object[stationId]['length'] = data.length
    object[stationId]['data'] = data
    stationsData.push(object)
  })
})

// Read stations 
fs.createReadStream(directory + 'asfdsfsd.csv')
  .pipe(csv({
    skipLines: 3
  }))
  .on('data', function (row) {
    if (stationIds.includes(parseInt(row['Station ID']))) {
      // console.log(row)
      stations.push(row)
    }
  })
  .on('end', function () {
      // console.log(stations)
  })

1 个答案:

答案 0 :(得分:1)

您可以将流的处理包装在Promise中,然后等待直到读取所有数据。之后,您可以处理最终文件。这仍然需要一些错误处理,但是应该给您一些开始:

// Read content of files 
async function processStationsCsv(directory, csvDataFiles) {
    let stationsIds = [];
    let stationsData = [];
    for (const csvFile of csvDataFiles) {
        await readStationDataFromFile(directory + csvFile, stationsIds, stationData);
    }

    let stations = [];
    await new Promise(resolve => {
        // Read stations 
        fs.createReadStream(directory + 'asfdsfsd.csv')
            .pipe(csv({
                skipLines: 3
            }))
            .on('data', row => {
                if (stationsIds.includes(parseInt(row['Station ID']))) {
                    stations.push(row)
                }
            })
            .on('end', () => {
                resolve();
            })
    })

    console.log(stations);

}

function readStationDataFromFile(filePath, stationIds, stationsData) {
    return new Promise(resolve => {
        fs.createReadStream(filePath)
            .pipe(csv())
            .on('data', function (row) {
                data.push(row)
            })
            .on('end', function () {
                const object = {}
                let stationId = parseInt(file.substr(0, file.indexOf('.')))
                stationIds.push(stationId)
                object[stationId] = {}
                object[stationId]['length'] = data.length
                object[stationId]['data'] = data
                stationsData.push(object)
                resolve();
            })
    });
}

// call it with the directory path and the array of csvDataFiles-paths
processStationsCsv(directory, csvDataFiles);