【问题标题】:Unexpected behavior when using csv-parser node module使用 csv-parser 节点模块时的意外行为
【发布时间】:2019-05-10 01:46:57
【问题描述】:

我正在尝试将 csv 文件的标头放入数组中,并尝试使用 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)

【问题讨论】:

    标签: javascript node.js node-csv-parse


    【解决方案1】:

    您的代码使用异步回调。这意味着,事件处理程序((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 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的形式中。

    【讨论】:

    • 我仍然不清楚如何将omg 的值返回到全局执行上下文,以便它可以在程序的其他地方使用。
    • omg 将永远是 undefined。但我在答案中添加了一个代码示例,向您展示如何将 headers 数组传递给函数。
    猜你喜欢
    • 2012-10-15
    • 2012-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-04
    • 2017-10-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多