2

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

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

2) 为什么我的 getFields 函数没有返回新填充的标题数组?我可以 console.log 函数内部的所有新元素的结果数组,但我实际上不能返回充满元素的数组——它一直返回一个空数组。

这是代码:

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)
4

1 回答 1

-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 的形式隐藏起来。

于 2019-05-07T19:32:56.253 回答