javascript - NodeJS CSVReader - 带有 csv-parse 的 createReadStream 返回空数组
问题描述
我有一个 CSV 阅读器类,它带有两个参数(文件路径和模型)。文件路径是 .csv 文件的路径,模型是构建 .csv 文件的模型。数据将存储在输出数组中。它有一个问题,因为当我返回数组时,它是空的。但是当我控制台记录数组时,它里面有数据。有人能帮我吗?
索引.js
const parse = require('csv-parse')
const fs = require('fs');
const output = [];
class CSVReader{
static GetRecord(filePath, model){
fs.createReadStream(filePath)
.pipe(parse({columns: false, delimiter: ',', trim: true, skip_empty_lines: true}))
.on('readable', function (){
let record
while (record = this.read()){
let city = model.create(record)
output.push(record)
}
})
.on('end', function (){
//console.log(output);
})
return output;
}
}
module.exports = CSVReader;
我用 Jest 测试了文件,但它有一个问题,正如预期的那样是 6,但我收到了 []
索引.test.js
const CSVReader = require('../src/Index');
const City = require('../src/Models/City')
test('Can Read CSV File', () => {
let filePath = 'data/worldcities.csv';
let records = CSVReader.GetRecord(filePath, City);
expect(records.length).toBe(6);
});
解决方案
tl;博士:
这是一个异步调用,因此您不能只返回响应并期望它起作用。您需要使用 Promise API 和异步函数。
是什么让这个异步?
所有 Node.js fs
API 都是异步的(不包括fs.*Sync
函数)。
我如何使用 Promise?
Promise
您可以在函数顶部返回 a ,然后传递回调:
return new Promise((resolve, reject) => { /* callback */ });
修复代码
// all of this is fine
const parse = require('csv-parse')
const fs = require('fs');
// remove the const output = []; as this will cause problems
class CSVReader{
// this needs to be async
static async GetRecord(filePath, model){
// return a promise
return new Promise((resolve, reject) => {
// assign output here (https://stackoverflow.com/a/66402114/14133230)
const output = [];
fs.createReadStream(filePath)
.pipe(parse({columns: false, delimiter: ',', trim: true, skip_empty_lines: true}))
.on('readable', function (){
let record
while (record = this.read()){
let city = model.create(record)
output.push(record)
}
// you may need to call WriteStream#close() here
})
.on('end', function (){
// output is available here
// resolve the promise
resolve(output);
})
});
}
}
module.exports = CSVReader;
使用新的基于 Promise 的函数
const CSVReader = require('../src/Index');
const City = require('../src/Models/City')
test('Can Read CSV File', () => {
let filePath = 'data/worldcities.csv';
let records = CSVReader.GetRecord(filePath, City); // type Promise
records.then((response) => { // when promise fills
expect(response.length).toBe(6);
});
});
推荐阅读
- python - 如何在 SciPy.optimize.minimize 中定义不连续的边界
- python-3.x - 应用于嵌套列表时,函数不会更改值
- html - HTML / CSS没有链接?
- python - 将变量中的两个数字相加
- excel - 在 Excel 中使用分隔符将单行单元格拆分为多行单元格
- azure-cosmosdb - 在 Azure Cosmos DB Graph API 中添加或获取顶点
- java - 一个简单的 curl 命令导致了这种荒谬
- awk - awk 命令或 sed 命令
- ios - 使用 dateFormat 将日期转换为日期
- xamarin.android - SliderRange 可以在 xamarin android 上使用吗?