javascript - 使用 csv-parser Node 模块时的意外行为

标签 javascript node.js node-csv-parse

我正在尝试将 csv 文件的 header 放入数组中,并尝试使用 csv-parser 来执行此操作。有两件事我在这里想不通:

1) 为什么代码最后一行的 console.log 比其他任何东西都先触发?这也意味着我尝试记录的变量值未定义。

2) 为什么我的 getFields 函数不返回新填充的标题数组?我可以从函数内部控制台记录结果数组及其所有新元素,但实际上我无法返回充满元素的数组——它一直返回一个空数组。

代码如下:

const express = require('express')
const app = express()
const port = 3000
const csv = require('csv-parser')  
const fs = require('fs')

function getFields (filePath) {
  let results = [];
  fs.createReadStream(filePath)
    .pipe(csv())
    .on('headers', (headers) => {
      let values = Object.values(headers);
      values.forEach(function(element) {
        results.push(element);
      });
      console.log('I am actually getting results here: ', results);
      return results;
   });
}

const omg = getFields(thisIsAFilePath)
console.log('This console.log is firing before anything else: ', omg)

最佳答案

您的代码使用异步回调。这意味着,事件处理程序((headers) => {...} 函数)在触发事件(在本例中为 headers)时执行。这是异步发生的,而其余脚本继续。

这意味着会发生以下情况:

  1. 函数声明
  2. 函数被调用,因为它什么都不返回(甚至没有 return 语句),undefined 存储在 omg<
  3. 执行console.log调用
  4. 在未来的某个时候,事件 headers 被触发,将执行函数 (headers) => { ... }

所以如果你需要结果,你需要把代码放在回调里面或者像这样从里面调用一个函数:

function handleHeaders(headers) {
  console.log(headers);
}

function getFields (filePath) {
  let results = [];
  fs.createReadStream(filePath)
    .pipe(csv())
    .on('headers', (headers) => {
      handleHeaders(headers);
   });
}

替代方案: promise

或者,您可以使用 Promise API ,这将允许您像这样编写代码:

(async () => {
    function getFields(filePath) {
        return new Promise(resolve => {
            let results = [];
            fs.createReadStream(filePath)
                .pipe(csv())
                .on('headers', (headers) => {
                    let values = Object.values(headers);
                    values.forEach(function (element) {
                        results.push(element);
                    });
                    console.log('I am actually getting results here: ', results);
                    resolve(results);
                });
        });
    }

    const omg = await getFields(thisIsAFilePath)
    console.log('This console.log is firing before anything else: ', omg)
})();

请记住,代码也是异步执行的,它只是以 Promises 的形式隐藏。

关于javascript - 使用 csv-parser Node 模块时的意外行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56029298/

相关文章:

javascript - 如何在 javascript 中获取此类的 href?

javascript - select2 bootstrap 大小问题

node.js - NodeJS - 数据类型、变量、控制结构、迭代

node.js - 使用不带循环的 csv-parse

javascript - 将 Backbone.js 用于静态内容、JavaScript 较多的网站?

Javascript文件对象相当于java中的文件对象

javascript - Sequelize.INTEGER 与 DataTypes.INTEGER

javascript - 为什么 Node 不识别这个导入的函数?

typescript - 使用 'csv-parse/sync' 库后 Jest 测试失败