使用 Bluebird 将所有 csv 文件读入节点 js 中的 1 个 JSON 对象数组
Posted
技术标签:
【中文标题】使用 Bluebird 将所有 csv 文件读入节点 js 中的 1 个 JSON 对象数组【英文标题】:read all csv files into 1 JSON object array in node js with Bluebird 【发布时间】:2016-10-18 15:11:59 【问题描述】:我是在 nodeJS 中使用 Promise Bluebird 的新手。
我想将特定目录中的所有 CSV 文件读入 1 个 JSON 对象数组并显示结果。
步骤如下:
-
读取目录获取文件名(调用函数readDir)
使用循环读取每个 CSV 文件(lodash forOwn 循环)并将内容存储在 JSON 对象数组中(调用函数 ReadFile)
将 JSON 对象数组(使用 Lodash 分配函数)与主要 JSON 对象数组(名为 data_Warehouse)合并,以便将所有数据存储到 1 个 JSON 对象数组中。
将所有 CSV 文件数据保存到 JSON 对象数组 data_Warehouse 后,在 console.log(.then 部分)中显示 data_Warehouse。
检查是否一切按计划进行,我在代码之间放入了console.log。 问题是这些过程没有按正确的顺序完成。我尝试使用 Bluebird,但它仍然没有按计划进行。
您能帮我解决这个问题吗?
这是我的输出:
输出:加载\Book1.csv
输出:加载\Book2.csv
输出:加载\Book3.csv
结果:
加载\Book1.csv 101
加载\Book2.csv 102
加载\Books.csv 103
如您所见,行输出“结果”应该是最后一行,但它在 JSON 对象数组 data_Warehouse 为空的过程中较早。
var Converter = require("csvtojson").Converter;
var converter = new Converter();
var _ = require('lodash');
var r = require('rethinkdbdash')(config.rethinkdb);
var fs = Promise.promisifyAll(require('fs'));
readDir()
.then(function(v)
var data_Warehouse=;
_.forOwn(v, function(index)
console.log('output:' + index);
_.assign(data_Warehouse, readFile(index));
);
return mine;
).then(function(w)
console.log('Results:' + w.length);
)
function readDir()
return fs.readdirAsync(dir).map(function (fileName)
var path = Path.join(dir, fileName);
return fs.statAsync(path).then(function(stat)
return stat.isDirectory() ? readDir(path) : path;
);
).reduce(function (a, b)
return a.concat(b);
, []);
function readFile(fileName)
var converter = new Converter();
fs.createReadStream(fileName).pipe(converter);
converter.on("end_parsed", function (jsonArray)
console.log(fileName + ' ' + jsonArray[0].Order_ID);
return jsonArray;
)
我更改了我的代码(使用了 promisifyAll),现在能够读取指定目录中的所有文件并以正确的顺序显示结果,但是现在使用 csvtojson 将读取的数据转换为每个文件上的 json问题。它会在 console.log('results: ' + result[Ticker].Order_ID); 之前显示'done....' (见下面的输出)。
var join = Promise.join;
var fs = Promise.promisifyAll(require("fs"));
var Converter = require("csvtojson").Converter;
var Promise = require('bluebird');
var dir='./load/';
fs.readdirAsync(dir).map(function(fileName)
var contents = fs.readFileAsync(fileName).catch(function ignore() );
return join(fileName, contents, function(fileName, contents)
return
fileName: fileName,
contents: contents
);
).each(function(file)
console.log('File Name: ' + file.fileName + '\n');
console.log('output: ' + file.contents + '\n');
var converter = new Converter();
var temp = file.contents.toString();
var tmp;
converter.on("end_parsed", function() );
converter.fromString(temp, function(err, result)
tmp = result;
for(var Ticker in result)
console.log('results: ' + result[Ticker].Order_ID);
);
console.log('___________________');
return tmp;
).then(function(contents)
console.log('Done.............');
)
我现在的输出是:
文件名:Book1.csv
输出:Order_ID、数量、价格、日期、备注
123、1000、12.95、10/8/2015、测试 786、100、7.95、11/6/2015、test2
文件名:Book2.csv
输出:Order_ID、数量、价格、日期、备注
4526、800、2.95、4/1/2015、test3 129、10、3.66、1/23/2014、test4
完成......
结果:123
结果:786
结果:4526
结果:129
如何以正确的顺序将转换器 csvtojson 带回,以便“完成...”在流程结束时结束?
已编辑:
现在我已经承诺 csvtojson 但由于某种原因它不起作用。
var join = Promise.join;
var fs = Promise.promisifyAll(require("fs"));
var Converter = require("csvtojson").Converter;
var Promise = require('bluebird');
var dir='./load/';
jsons= function(data)
var converter = new Converter();
var output;
converter.on("end_parsed", function() );
converter.fromString(data, function(err, result)
for(var Ticker in result)
console.log('results: ' + result[Ticker].Ticker);
output = result;
);
return output;
;
var conversionJsons = Promise.promisifyAll(jsons);
fs.readdirAsync(dir).map(function(fileName)
var contents = fs.readFileAsync(fileName).catch(function ignore() );
return join(fileName, contents, function(fileName, contents)
return
fileName: fileName,
contents: contents
);
).each(function(file)
console.log('File Name: ' + file.fileName + '\n');
console.log('output: ' + file.contents + '\n');
console.log('___________________');
var temp = file.contents.toString();
conversionJsons(temp).then(function(result) // <----Error here for then
console.log("results are: "+ result);
return result;
);
).then(function(contents)
console.log('Done.............');
)
我收到以下错误:
“无法读取未定义的属性'then'”
您能帮我解决这个问题吗?
【问题讨论】:
【参考方案1】:好吧,您正在遭受race condition 的困扰,因为您的操作是异步运行的。
我的建议是按照你想要的顺序使用一系列承诺和chain them,然后等到所有内容都完成后再发送你想要的结果,你应该使用promise.all
【讨论】:
我现在更改了我的代码。所有文件都在开始时读取。转换 csvtojson 是我现在的问题。 尝试将所有的promise包装成一个数组,然后使用promise.all 我改变了我的代码来包装承诺,但我可以错误“无法读取未定义的属性'then'”以上是关于使用 Bluebird 将所有 csv 文件读入节点 js 中的 1 个 JSON 对象数组的主要内容,如果未能解决你的问题,请参考以下文章