使用node.js和ES6/ES7功能逐行读取CSV文件

5

在Python中逐行读取CSV文件(即不将整个文件加载到内存中)很简单:

import csv
for row in csv.reader(open("file.csv")):
    print(row[0])

使用node.js时,需要使用类似 node-csv 、流和回调函数。

是否可以使用新的ES6/ES7功能,如迭代器、生成器、Promises和异步函数,以一种更像Python代码的方式迭代CSV文件的行?

理想情况下,我希望能够编写类似以下的内容:

for (const row of csvOpen('file.csv')) {
  console.log(row[0]);
}

(再次强调,不需一次性将整个文件加载到内存中。)

请查看http://papaparse.com/。 - Cloxure
1
FYI,ES7只引入了Array#includes和指数运算符。这两个都对此无济于事。异步函数是一个提案。即使使用异步函数,您仍需要在顶层使用回调。 - Felix Kling
1
@Iceman:如果你能编写一个可以与我问题底部的for循环一起工作的“csvOpen”函数,我会很高兴看到它! - danvk
ES7已经发布。它不包含异步函数:http://www.ecma-international.org/ecma-262/7.0/。异步函数返回一个Promise p,因此在顶层你有asyncFunc.then(result => ...) - Felix Kling
1
审查 TC39 提案列表,看起来我正在寻求异步迭代器(Asynchronous Iterators),目前处于第二阶段。他们的示例与我的问题非常相似。祈祷好运! - danvk
显示剩余4条评论
1个回答

1

我不熟悉node-csv,但听起来使用生成器的迭代器应该可以做到。只需将其包装在任何异步回调API周围:

let dummyReader = {
  testFile: ["row1", "row2", "row3"],
  read: function(cb) {
    return Promise.resolve().then(() => cb(this.testFile.shift())).catch(failed);
  },
  end: function() {
    return !this.testFile.length;
  }
}

let csvOpen = url => {
  let iter = {};
  iter[Symbol.iterator] = function* () {
    while (!dummyReader.end()) {
      yield new Promise(resolve => dummyReader.read(resolve));
    }
  }
  return iter;
};

async function test() {
  // The line you wanted:
  for (let row of csvOpen('file.csv')) {
    console.log(await row);
  }
}

test(); // row1, row2, row3

var failed = e => console.log(e.name +": "+ e.message);

请注意这里的row是一个promise,但足够接近。将其粘贴到babel中。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接