在回调函数之外访问由 node.js 中的 readline 和 fs 解析的数据

Posted

技术标签:

【中文标题】在回调函数之外访问由 node.js 中的 readline 和 fs 解析的数据【英文标题】:Accessing data parsed by readline & fs in node.js outside of the callback function 【发布时间】:2017-05-24 13:00:02 【问题描述】:

这个问题与已经有答案的链接不同。特别是这段代码改编自 node.js 文档,关于 fs 和 readfile 的使用以及寻找文件结束标志,我了解到的是 readfile.close 方法。感谢您的回答。

我在本地编写了一个小实用程序来尝试将带有空行分隔程序的 key:value 对的文本文件转换为 JSON 文件以在 React 项目中使用。

我直接从 node.js 文档中获得了 readline 函数的基础。我在我的 mac 上使用节点 6.9.0

这里是完整的脚本:

const readline = require('readline');
const fs = require('fs');

const rl = readline.createInterface(
  input: fs.createReadStream('usat-ncaa-programs.txt')
);

var newPairs=["test"];
rl.on('line',
  function (line) 
  if (line===null)
    newPairs.push("], [ ")
   else if (line) 
    var keyValue = line.match(/^(.*):(.*)/)
    var newKeyValuePair =  "'" + keyValue[1].trim() + "':  '" + keyValue[2].trim() + "'"
    newPairs.push(newKeyValuePair)
    //console.log (newKeyValuePair)
  

)

console.log(newPairs)

输入文件是这样的(大约有12个程序),我只包含了2 1/2,所以你可以看到格式:

University: Arizona State University
Division: I
University Home Page: http://www.asu.edu/
Recruiting Link: https://questionnaire.acsathletics.com/Questionnaire/Questionnaire.aspx?&SPSID=1061112&SPID=177408&DB_LANG=C&DB_OEM_ID=30300&q=2015&s=159130&o=143
Team Homepage: http://www.thesundevils.com/index.aspx?path=triathlon
Head Coach: Cliff English
w: 480.965.0546
e: cliff.endlish@asu.edu
bg-color: #990033
color: #FFB310

University: Belmont Abby College
Division: II
University Home Page: http://belmontabbeycollege.edu/
Recruiting Link: https://coach.scoutforce.com/p/414f3219dd
Team Homepage: http://abbeyathletics.com/sports/wtri/index
Head Coach: Nick Radkewich
w: 704.461.5010
e: NicholasRadewich@bac.edu
Twitter: https://twitter.com/AbbeyTri
bg-color: #FFFDD0
color: #DC143C

University:Black Hills State University 
Division: II
University Home Page: http://www.bhsu.edu/
...

我的问题是,虽然我可以逐行读取文本文件并解析一些看起来像 JSON 文件的信息,但我无法在回调函数之外访问该数据。

我不知道如何将这些数据保存到新文件中,甚至不知道如何将对象输出到我的控制台进行剪切和粘贴并手动编辑。

在上面的脚本中,变量 newPairs 的记录输出是 ["test"] 而不是我试图完成的逐行解析。

如果我将 console.log 放在回调中,我会在每次读取文件时记录信息。我只想在文件完成后处理数据。

我在fsreadline 的节点文档中没有找到EOF 或类似标志。

此外,如果有更简单的方法可以将我输入的数据转换为 JSON 格式,我很乐意听到。提前致谢。

【问题讨论】:

你应该阅读Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference 谢谢我看了一下。我知道这与异步有关,但对 readfile 方法没有经验。再次感谢,感谢您的帮助。 我只能建议始终查看完整的文档。在这种情况下:nodejs.org/api/readline.html#readline_event_close。您可能还想了解更多关于流的信息:github.com/substack/stream-handbook 我绝对可以了解更多关于流的信息。我确实阅读了 readline 上的完整文档,无论出于何种原因,可能是因为这对我来说是新的,它并没有作为这个问题的答案或解决方案跳出来。我一直在寻找指示文件或流结束的“on”方法中的特定内容。感谢您提供有关流的其他建议。 当然,如果你不知道,你就无法知道;)大多数作为事件发射器/公开函数来绑定事件的 Node API(即.on)都有一个关于什么的部分它们发出的事件以及这些事件的作用。现在你知道了 :) 编码快乐! 【参考方案1】:

你要明白回调函数是异步执行的。这意味着console.log(newPairs) 在您的回调之前执行,因此它只会导致“测试”。

你应该听 Readline 的 close event,像这样:

rl.on('close', function() 
  console.log(newPairs);
);

如文档所述:

当发生以下情况之一时,会发出“关闭”事件:

调用 rl.close() 方法和 readline.Interface 实例 已放弃对输入和输出流的控制; 输入流接收它的“结束”事件;输入流接收 -D 以表示传输结束(EOT); 输入流接收 -C 以发出 SIGINT 信号,并且在 readline.Interface 实例上没有注册 SIGINT 事件侦听器。 在不传递任何参数的情况下调用侦听器函数。

readline.Interface 实例应被视为“完成” 一旦发出“关闭”事件。

所以这将是您正在寻找的“EOF”:-)

【讨论】:

我知道它是异步的,但我不知道如何使用它来读取完整的文件。我会尝试关闭事件,看看是否可以解决问题。我正在寻找一种“文件结尾”的方法。这有效,我已将其标记为答案。感谢您的帮助。 我已经用 doco 的摘录更新了答案 好吧,它不会让我接受答案,我要去睡觉重新开始......早上会接受答案。再次感谢。 不用担心。祝你好运!【参考方案2】:

我知道这是一个老问题,但答案对我没有帮助。你可以使用这样的承诺:

function readLineAsync()
 var data = [];
 var i = 0;
 return new Promise((resolve,reject)=>
     var lineRead = readLine.createInterface(
         input:fs.createReadStream('path.to.file')
     )
     lineRead.on('line',(line)=>
        data[i] = line;
        i++; 
     )
     lineRead.on('close',()=>
        resolve(dataCsv);
     )
 )

(async function() console.log(await readLineAsync())())

【讨论】:

以上是关于在回调函数之外访问由 node.js 中的 readline 和 fs 解析的数据的主要内容,如果未能解决你的问题,请参考以下文章

Node / JS:奇怪的嵌套回调函数

Node-异步编程

node.js学习笔记——回调函数

JavaScript/node.js:尝试访问某个函数之外的对象属性时获取 NULL

在Node js中的功能之外无法访问外部IP

我们如何将字符串从回调函数返回到 node.js 中的根函数?