如何从我的服务返回 CSV 数据 - 异步/等待问题?

phy*_*boy 1 javascript csv node.js

我试图在我的 API 中加载一些 CSV 数据,以便我可以操作它并传递到我的前端,但是我在返回数据时遇到了一些问题。

我在这里使用fast-csv进行解析。

服务.js

const fs = require('fs');
const csv = require('fast-csv');

module.exports.getFileContents = (filepath) => {
    let data = [];

    fs.createReadStream(filepath)
        .pipe(csv.parse({ headers: true }))
        .on('error', error => console.error(error))
        .on('data', row => data.push(row))
        .on('end', () => {
            console.log(data) // This will print the full CSV file fine
            return data;
        });
};
Run Code Online (Sandbox Code Playgroud)

路线.js

router.get('/data/:filename', (req, res) => {
  const file = FS.getFileContents(testUrl + '/' + req.params.filename + '.csv');
  console.log(file); // This prints 'undefined'
  res.send(file);
});
Run Code Online (Sandbox Code Playgroud)

我可以从服务中打印出 CSV 内容,但我只是从实际路线中得到“未定义” 。有人可以指出我缺少什么吗?

jar*_*mod 6

这是 JavaScript 代码的常见问题,如下所示。

.on('end', () => {
    console.log(data);
    return data;
 });
Run Code Online (Sandbox Code Playgroud)

您的端处理程序是一个匿名回调函数(因为() =>),因此当您 时return data,您将从端处理程序回调函数中返回数据。您没有从封闭getFileContents()函数中返回数据。

以下是编写此类代码的典型方法:

const getFileContents = async (filepath) => {
  const data = [];

  return new Promise(function(resolve, reject) {
    fs.createReadStream(filepath)
      .pipe(csv.parse({ headers: true }))
      .on('error', error => reject(error))
      .on('data', row => data.push(row))
      .on('end', () => {
        console.log(data);
        resolve(data);
      });
  });
}
Run Code Online (Sandbox Code Playgroud)

然后,按如下方式调用它,尽管这必须在异步函数内:

const data = await getFileContents('games.csv');
Run Code Online (Sandbox Code Playgroud)

这里发生的事情如下:

  • getFileContents现在是异步的并返回一个承诺
  • resolve(data)执行时 CSV 数据将可用
  • 调用者可以等待此承诺的履行/解决以获取数据