使用Bluebird将所有csv文件读入节点j中的1个JSON对象数组
我在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中显示data_Warehouse(.then部分)。
检查是否都按照计划,我把代码之间的console.log。 问题是这个过程不是按照正确的顺序完成的。 我试图使用蓝鸟,但它仍然没有按照计划去。
你能帮我解决这个问题吗?
这是我的输出:
输出:负载\ Book1.csv
输出:负载\ Book2.csv
输出:负载\ Book3.csv
结果:{}
加载\ Book1.csv 101
load \ Book2.csv 102
加载\ Books.csv 103
正如你所看到的,行输出“results”应该是最后一个,但是在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,数量,价格,date,备注
123,1000,12.95,10 / 8/2015,test 786,100,795,11 / 6/2015,test2
文件名:Book2.csv
输出:Order_ID,数量,价格,date,备注
4526,800,295,4 / 1/2015,test3 129,10,3.66,1 / 23/2014,test4
完成………….
结果:123
结果:786
结果:4526
结果:129
如何将转换器csvtojson恢复到正确的顺序,以便“完成…”处理结束?
编辑:
现在我已经promisify 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.............'); })
我得到以下错误:
“不能读取属性”,然后“未定义”
你能帮我解决这个问题吗?
那么,由于你的操作是asynchronous运行的,你正在遭受那里的竞争状态 。
我所build议的是使用一系列的承诺,并按照你想要的顺序链接它们 ,然后等到所有的结果都按照你的意愿发送,你应该使用promise.all