使用csv-parser节点模块时的意外行为

时间:2019-05-07 19:27:21

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

我正在尝试将csv文件的标头放入数组中,并尝试使用csv-parser这样做。我在这里找不到两件事:

1)为什么最后一行的console.log会先触发?这也意味着我尝试记录的变量值未定义。

2)为什么我的getFields函数不返回新填充的标头数组?我可以从函数内部用console.log记录具有所有新元素的results数组,但是我实际上不能返回充满元素的数组-它一直返回空数组。

代码如下:

body {

    font-family: 'Roboto Condensed', sans-serif;  
    font-size: 16px;
    text-transform: uppercase;
    font-weight: bold;
}

1 个答案:

答案 0 :(得分:0)

您的代码使用异步回调。这意味着,事件(在这种情况下为(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的形式隐藏了。