首页 > 解决方案 > 在 csv-parser 之后对象值未定义

问题描述

我不确定为什么我在运行后会变得未定义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);

测试.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

标签: javascriptnode.jscsv

解决方案


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

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/

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


推荐阅读