使用' readline'进行node.js程序的同步执行

时间:2016-08-31 23:37:06

标签: javascript node.js asynchronous readline synchronous

我遇到一些问题,让节点的异步性与我合作,以及经过数小时的回调和谷歌搜索;我终于转向你了。

我有一个程序需要使用节点的readline模块从文件中读取行。此文件包含传递给我的节点程序中定义的某些异步函数的数据。成功读取和处理所有数据后,需要将此数据解析为JSON格式,然后输出。

我的问题是,当我调用:readLine.on('close', function() { ...... }时,这是在异步函数完成运行之前运行的,因此我只剩下一个输出,但是程序继续运行异步函数。

我已经创建了一个简单的函数框架,可以更清楚地解释我的情况:

function firstAsyncFunc(dataFromFile) {
   //do something asynchronously

   return processedData;
}


function secondAsyncFunc(dataFromFile) {
  //do something else asynchronously

  return processedData;
}


//create readline 
var lineReader = require('readline').createInterface({
  input: require('fs').createReadStream('data.txt')
});


//array to hold all the data processed
var totalDataStorage; 


//read file 
lineReader.on('line', function(line) {

  var processedData = firstAsyncFunction(line);
  var moreProcessedData = secondAsyncFunction(line);


  //store processed data and concatenate into one array
  var tempDataStorage = [{ 'first': processedData, 'second': moreProcessedData }]
  totalDataStorage = totalDataStorage.concat(tempDataStorage);

}).on('close', function() {

  var JSONString = JSON.stringify(... //create JSON for totalDataStorage ...);
  console.log(JSONString); //DOESN'T OUTPUT ANYTHING!

});

我试图在第一个/第二个AsynFunction中添加一个回调函数,我试图对程序的单独函数进行读取和解析,并创建回调,以便只在读取完成时调用解析,但这些解决方案都没有似乎工作正常,我真的很挣扎 - 所以任何帮助都会受到赞赏。

谢谢!

编辑:data.txt文件的格式为

IPData1 DataCenter1
IPData2 DataCenter2
...
IPDataN DataCenterN

我使用str.split("")来获取相应的值,然后适当地传递它们。 IPData是一个数字,DataCenter是一个字符串

2 个答案:

答案 0 :(得分:1)

异步函数不返回值,但您必须将回调函数传递给它。你的行

  

var processedData = firstAsyncFunction(line);

根本没有意义。如果您的data.txt文件看起来像这样

IPData1 DataCenter1
IPData2 DataCenter2
IPData3 DataCenter3

您可以按以下方式阅读数据

var fs = require('fs');
var rl = require('readline').createInterface({
  input: fs.createReadStream('data.txt')
});
var arr = [];

rl.on('line', a => {
  a = a.split(' ');
  arr.push({
    first: a[0],
    second: a[1]
  });
}).on('close', () => {
  console.log(JSON.stringify(arr, null, 2));
});

会记录

[
  {
    "first": "IPData1",
    "second": "DataCenter1"
  },
  {
    "first": "IPData2",
    "second": "DataCenter2"
  },
  {
    "first": "IPData3",
    "second": "DataCenter3"
  }
]

答案 1 :(得分:0)

我更改了以下内容并在本地工作。

  1. 使用承诺让您的生活更轻松。
  2. 删除.close,因为您没有在界面中定义输出。
  3.   

    发生以下任一情况时会发出'close'事件:

         
        
    1. 调用rl.close()方法,readline.Interface实例放弃了对输入和输出流的控制;
    2.   
    3. 输入流接收其“结束”事件;
    4.   
    5. 输入流接收-D以发信号传输结束(EOT);
    6.   
    7. 输入流接收-C以发信号SIGINT,并且在readline.Interface实例上没有注册SIGINT事件侦听器。
    8.   
    function firstAsyncFunc(dataFromFile) {
      return new Promise(function(resolve, reject) {
        //do something asynchronously
        resolve(result);
      })
    }
    
    function secondAsyncFunc(dataFromFile) {
      return new Promise(function(resolve, reject) {
        //do something asynchronously
        resolve(result);
      })
    }
    
    //create readline 
    var lineReader = require('readline').createInterface({
      input: require('fs').createReadStream('data.txt')
    });
    
    //array to hold all the data processed
    var totalDataStorage;
    
    //read file 
    lineReader.on('line', function(line) {
      Promise.all([
          firstAsyncFunc(line),
          secondAsyncFunc(line)
        ])
        .then(function(results) {
          var tempDataStorage = [{
            'first': results[0],
            'second': results[1]
          }];
          // i'd use push instead of concat
          totalDataStorage = totalDataStorage.concat(tempDataStorage);
        });
    })