【问题标题】:Object value undefined after csv-parser在 csv-parser 之后对象值未定义
【发布时间】:2020-03-21 09:34:18
【问题描述】:

我不确定为什么我在运行console.log(class1.roster) 后会得到未定义,即使我已在上一个命令class1.importRoster(createRoster(filePath)); 中将数组传递给该对象。我会很感激一个解释和一种可能的方式来查看 class1.roster 是否有价值。我正在使用 npm 包csv-parser。这是我的 MWE 和 test.csv 的内容

mwe.js

const fs = require ('fs');
const csv = require('csv-parser');
const filePath = 'test.csv'
let classRoster = [];

function schoolClass (subject, period, schoolYear) {
  this.subject = subject;
  this.period = +period;
  this.schoolYear = schoolYear;
  this.importRoster = function (roster) {
    this.roster = roster;
  }
}

function Student (firstName,lastName,ID,grade,period) {
  this.firstName = firstName;
  this.lastName = lastName;
  this.ID = ID;
  this.grade = grade;
  this.period = period;
}

function createRoster (path)  {
  fs.createReadStream(path)
  .pipe(csv())
  .on('data', (data)=>{
    classRoster.push(new Student(data.first_name, data.last_name, data.id, data.grade, data.period))
  })
  .on('end', ()=>{
    console.log("Done");
    return classRoster;
  })
}

class1 = new schoolClass("GER", 3, "19-20");

console.log(class1);

class1.importRoster(createRoster(filePath));

console.log(class1.roster);

test.csv

first_name,last_name,grade,id,period
Blondy,Debrett,10,0217842058,3
Nester,Langstrath,10,2574570346,3
Waldon,Trunby,11,4785462996,8
Lark,Alsopp,11,0039229732,7
Almira,Baistow,12,1272978281,3
Carmela,Abberley,12,7279500295,8
Cristabel,Soanes,10,3086318686,5
Currie,Milton-White,11,8123679871,8
Alexei,Everist,11,2538149622,7
Lina,Hehir,9,1345944671,3

【问题讨论】:

    标签: javascript node.js csv


    【解决方案1】:

    你在这里没有返回任何东西:

    function createRoster (path)  {
      fs.createReadStream(path)
      .pipe(csv())
      .on('data', (data)=>{
        classRoster.push(new Student(data.first_name, data.last_name, data.id, data.grade, data.period))
      })
      .on('end', ()=>{
        console.log("Done");
        return classRoster;
      })
    }
    

    在这里,您正在调用流的on 函数并传递两个参数 - 要侦听的事件和当流发出该事件时要运行的函数。该匿名函数的返回值不会被任何东西消耗。

      .on('end', ()=>{
        console.log("Done");
        return classRoster;
      })
    

    这里还有一些其他潜在的陷阱,即您将数据推送到的全局 classRoster 变量。如果您希望它成为全局缓存,则没有理由调用importRoster,因为您可以直接引用它。但是,多次调用createRoster 将继续将数据推送到同一个数组。

    看起来您可能应该重组您的代码以采用异步格式。您可以使用库的同步 API,但这可能会导致性能问题,具体取决于您的用例:https://csv.js.org/parse/api/sync/

    由于其简单性,如果您不需要可扩展性并且您的数据集适合内存,那么这是推荐的方法。它更容易使用,但代价是不可扩展。

    【讨论】:

    • 我是异步函数的新手,如何在不使用同步 API 的情况下将实际值推送到 class1.roster?
    • @1028 有几个选项。您可以将实例传递给createRoster 并将其设置在“结束”回调中。您可以让createRoster 返回流并将on('end'...) 链接到createRoster 之外。您可以从 createRoster 返回一个 Promise,这是处理异步逻辑的常用方法:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
    • 我有一个用 promise 包装 csv-parse 管道函数的示例 - stackoverflow.com/q/66402555/3761234
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-03
    • 1970-01-01
    • 2018-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多