使用'readline'同步执行node.js程序
我遇到了一些问题,使节点的asynchronous性与我合作,经过几个小时的callback和Googlesearch; 我终于转向你们。
我有一个程序,需要使用节点的readline模块从文件中读取行。 该文件包含传递给在我的节点程序中定义的一些asynchronous函数的数据。 一旦所有的数据都被成功的读取和处理,这个数据需要被parsing成JSON格式,然后输出。
我的问题是,当我调用: readLine.on('close', function() { ...... }
,这是在asynchronous函数完成运行之前运行,因此我留下一个什么也没有输出,但程序一直运行asynchronousfunction。
我创build了一个简单的函数框架,可以更清楚地解释我的情况:
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! });
我已经尝试添加一个callback到第一/ secondAsynFunction,我试图使读取和分析程序独立函数的位,并创buildcallback,以便只读时读取完成parsing,但似乎没有任何解决scheme工作,我真的很挣扎 – 所以任何帮助,将不胜感激。
谢谢!
编辑:data.txt文件的forms
IPData1 DataCenter1 IPData2 DataCenter2 ... IPDataN DataCenterN
我使用str.split(“”)来获得相应的值,然后适当地传递它们。 IPData是一个数字,DataCenter是一个string
asynchronous函数不会返回值,但您必须将callback函数传递给它。 你的线
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)); });
它会logging
[ { "first": "IPData1", "second": "DataCenter1" }, { "first": "IPData2", "second": "DataCenter2" }, { "first": "IPData3", "second": "DataCenter3" } ]
我改变了以下和本地工作。
- 使用承诺让您的生活更轻松。
- 删除.close,因为你没有在界面中定义的输出。
发生以下情况时,会发出“closures”事件:
- 调用rl.close()方法,readline.Interface实例放弃了对input和输出stream的控制;
- inputstream接收到“结束”事件;
- inputstream接收到-D信号表示发送结束(EOT);
- inputstream接收-C到信号SIGINT,并且没有在readline.Interface实例上注册的SIGINT事件侦听器。
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); }); })