使用Bluebird

时间:2016-06-16 22:30:11

标签: node.js csv promise bluebird

我是在nodeJS中使用Promise Bluebird的新手。

我想将特定目录中的所有CSV文件读入1个JSON对象数组并显示结果。

步骤如下:

  1. 读取目录以获取文件名(函数readDir被调用)
  2. 使用循环读取每个CSV文件(lodash forOwn循环)并将内容存储在JSON对象数组中(函数ReadFile调用)
  3. 将JSON对象数组(使用Lodash assign函数)与主JSON对象数组(名为data_Warehouse)合并,以便将所有数据存储到1个JSON对象数组中。
  4. 将所有CSV文件数据保存到JSON对象数组data_Warehouse后,在console.log中显示data_Warehouse(.then部分)。
  5. 检查是否全部按计划进行,我在代码之间放入console.log。 问题是进程不是由正确的顺序完成的。我试图使用Bluebird,但它仍然没有按计划进行。

    你可以帮我解决这个问题吗?

    这就是我的输出:

    输出:负载\ Book1.csv

    输出:负载\ Book2.csv

    输出:负载\ Book3.csv

    结果:{}

    load \ Book1.csv 101

    load \ Book2.csv 102

    load \ 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之前('结果:' +结果[Ticker] .Order_ID); (见下面的输出)。

    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 / 2015/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 / 23/2014,test4

    完成.............

    结果:1​​23

    结果:786

    结果:4526

    结果:1​​29

    如何以正确的顺序重新启用转换器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.............');
    
    })
    

    我收到以下错误:

    &#34;无法读取属性&#39;然后&#39;未定义&#34;

    你能帮我解决这个问题吗?

1 个答案:

答案 0 :(得分:1)

嗯,你在那里遇到了race condition,因为你的操作是异步运行的。

我建议的是按照你想要的顺序使用一系列的promises和chain them,等到所有人都完成后按照你的需要发送结果,你应该使用{{ 3}}