Javascript 使用';同步执行node.js程序;readline';

Javascript 使用';同步执行node.js程序;readline';,javascript,node.js,asynchronous,readline,synchronous,Javascript,Node.js,Asynchronous,Readline,Synchronous,在几个小时的回调和谷歌搜索之后,我在让节点的异步特性与我合作方面遇到了一些问题;我终于转向你们了 我有一个程序,需要使用node的readline模块从文件中读入行。此文件包含传递给节点程序中定义的某些异步函数的数据。成功读取和处理所有数据后,需要将这些数据解析为JSON格式,然后输出 我这里的问题是,当我调用:readLine.on('close',function(){……}时,这是在异步函数完成运行之前运行的,因此我的输出为零,但程序会继续运行异步函数 我创建了一个简单的函数框架,可以更清

在几个小时的回调和谷歌搜索之后,我在让节点的异步特性与我合作方面遇到了一些问题;我终于转向你们了

我有一个程序,需要使用node的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!

});
我曾尝试向first/secondAsynFunction添加回调函数,我曾尝试将程序的读取和解析位分开,并创建回调函数,以便仅在读取完成时调用解析,但这些解决方案似乎都不起作用,我真的很挣扎-因此,任何帮助都将不胜感激

谢谢


编辑:data.txt文件的格式如下

IPData1 DataCenter1
IPData2 DataCenter2
...
IPDataN DataCenterN

我使用str.split(“”)获取相应的值,然后适当地传递它们。IPData是一个数字,数据中心是一个字符串。异步函数不返回值,但您必须向其传递回调函数。您的行

var processedData=firstAsyncFunction(行)

没有任何意义。如果您的
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"
  }
]

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

  • 用承诺让你的生活更轻松
  • 删除。关闭,因为您没有在接口中定义输出
  • 发生下列情况之一时,将发出“关闭”事件:

  • 调用rl.close()方法,readline.Interface实例已放弃对输入和输出流的控制
  • 输入流接收其“结束”事件
  • 输入流接收-D到信号传输结束(EOT)
  • 输入流接收-C以发出SIGINT信号,并且在readline.Interface实例上没有注册SIGINT事件侦听器

  • 你能分享data.txt文件吗?我相信我能回答you@JaromandaX再次查看OP的代码。它是一个数组,而不是字符串。data.txt文件的格式为:
    IPData,datacenter
    。在实际程序中,我使用str.split(“”),将两个值拆分,然后将它们传递到必要的函数中。IPData是一个数字,数据中心值是一个字符串。希望如此helps@OliverOstach您的代码中有很多错误。您需要意识到,每次调用异步函数时,它都不会返回值,您还需要传递回调函数。您的行
    var processedData=firstAsyncFunction(行)
    毫无意义。此外,使用
    fs.readFile
    可以很容易地在几行中完成。啊,我忘了提到异步函数返回值!准确地说是字符串值!我现在就编辑它谢谢您的帮助,但不幸的是,这不起作用。我已经注册了一个回调函数来从异步函数,然后从
    行读取器中适当地调用它们。on('line',…)
    ,但我仍然有相同的问题
    。on('close')
    ,在异步函数完成并返回结果之前运行…(这是我的问题,我已经能够验证我所做的一切都是正确的!)@OliverOstach您根本无法理解异步函数是如何工作的。根据定义,异步函数无法返回值,因此请停止将其称为异步函数。如果它返回值,则它必须在触发
    onClose
    事件之前运行,因为这是
    v8
    引擎的工作方式。您认为我的答案如何不起作用?是吗你试过了吗?复制粘贴它以确保它正常工作。这似乎可以工作,但我似乎无法确定在何处记录数据,以便所有异步函数都在记录阶段执行
    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);
        });
    })