简体   繁体   English

如何从流中获取数据?

[英]How to get data out of a stream?

I would have expected that I got all the CSV data in the array, but for some reason I don't get anything.我原以为我得到了数组中的所有 CSV 数据,但由于某种原因,我什么也没得到。

Can someone explain why a is empty at the end?有人可以解释为什么a最后是空的吗?

const fs = require('fs');
const { parse } = require('csv-parse');

let a = [];

fs.createReadStream('./example.csv')
   .pipe(parse({ delimiter: ';', from_line: 2 }))
   .on('data', function (row) {
      a.push(row);
   })
   .on('end', function () {
      console.log('finished');
   })
   .on('error', function (error) {
      console.log(error.message);
   });

console.log(a);

createReadStream() runs parallel. createReadStream() 并行运行。 So after calling this function, the program continues and the next process is your console.log(a).所以调用这个函数后,程序继续,下一个过程就是你的console.log(a)。 Thats the idea behind streams because the program can continue running while the big file is read out.这就是流背后的想法,因为程序可以在读取大文件时继续运行。

The code inside the .on() functions is called later. .on() 函数内的代码稍后调用。 Thats why they are called "callbacks".这就是为什么它们被称为“回调”。

So you are logging the result before any data is read...所以你在读取任何数据之前记录结果......

As explained before the headstream runs in the background.如前所述,源流在后台运行。 You can wrap the stream in a promise to get the result.您可以将流包装在一个承诺中以获得结果。 Here is one possible solution:这是一种可能的解决方案:

const fs = require('fs');
const { parse } = require('csv-parse');

const readFile = async () => new Promise((resolve, reject) => {
    let a = [];
    fs.createReadStream('./example.csv')
        .pipe(parse({ delimiter: ';', from_line: 2 }))
        .on('data', function (row) {
            a.push(row);
        })
        .on('end', function () {
            resolve(a);
        })
        .on('error', function (error) {
            reject(error)
        });
});

readFile().then(data => console.log(data))

Your a is undefined because the code is executed asynchronously.a undefined ,因为代码是异步执行的。 The on() function is called after your console.log(a) is executed.在执行你的console.log(a)之后调用on()函数。

You can read the value of a inside the data event or the end event:您可以读取data事件或end事件内部的a的值:

fs.createReadStream('./example.csv')
   .pipe(parse({ delimiter: ';', from_line: 2 }))
   .on('data', function (row) {
      a.push(row);
      console.log(a) // <------- here
   })
   .on('end', function () {
      console.log('finished');
      console.log(a) // <------- here
   })
   .on('error', function (error) {
      console.log(error.message);
   });

One solution may be to use a Promise一种解决方案可能是使用Promise

const readCSVData = async () => new Promise((resolve, reject) => {
let a = []
fs.createReadStream('./example.csv')
   .pipe(parse({ delimiter: ';', from_line: 2 }))
   .on('data', function (row) {
      a.push(row);
   })
   .on('end', function () {
      // return the a value 
      resolve(a) 
   })
   .on('error', function (error) {
      reject(error)
   });
})

// ..... 

const foo = async () => {
  const data = await readCSVData()
  console.log(data)
}

// or
readCSVData().then(a => console.log(a))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM