Node.js readline 回调函数

3
我正在学习回调函数,但是我总是无法正确理解... 我想要读取一个文件,并将它的数据保存到全局变量中以便之后使用。
以下是我的代码:
var fs = require("fs");
var readline = require("readline");
var i = 0;
var total = 66; //put the total foldernames or total images (same number)
var folder_names = [];
var data = [];

lineReader = readline.createInterface({
    input: fs.createReadStream("folder-names and data.txt")
});


lineReader.on('line', function(line, dataCollector) {
    if(i<66)
        folder_names.push(line);
    else
        data.push(line);

    dataCollector(folder_names, data);
    i++;
});

var dataCollector = function(folder_names, data) {
    //console.log(folder_names);
}

console.log(folder_names[0]); //should have a value now.

什么有问题?我收到了:dataCollector不是一个函数的错误。
2个回答

7

这里你在使用dataCollector标识符进行阴影效果:

lineReader.on('line', function(line, dataCollector) {

这声明了dataCollector作为回调函数的第二个参数,遮蔽了脚本顶层的标识符。

line事件没有记录它提供回调函数的第二个参数,因此应该像这样:

lineReader.on('line', function(line) {

关于您提出的问题的扩展:
console.log(folder_names[0]); //should have a value now.
不应该这样做。为什么呢:参考如何从异步调用中返回响应?
在您的情况下,您可能希望在close事件处理程序中执行console.log操作。
lineReader
    .on('line', function(line) {
        if(i<66)
            folder_names.push(line);
        else
            data.push(line);

        dataCollector(folder_names, data);
        i++;
    })
    .on('close', function() {
        console.log(folder_names[0]); // has its values now
    });

我想让folder_names变量填充到lineReader函数中。我会更新我的问题。 - Florin Pop
@FlorinPop:你目前的问题是为什么会出现错误信息“dataCollector不是一个函数”。问题不应该是移动目标。这回答了那个问题。 - T.J. Crowder
我在描述中已经说明了我的需求:“我想读取一个文件,并将其数据保存到全局变量中以便稍后使用。” - Florin Pop
@FlorinPop:重点在于错误信息。我已经在上面添加了有关您的编辑的注释。 - T.J. Crowder
@FlorinPop:当你发布一个问题并说“但我遇到了这个错误”时,那就是问题的重点。无论如何,链接的问题解释了为什么你不能按照你现在的方式去做,以及应该怎么做;上面的内容则解释了为什么你会遇到这个错误。 - T.J. Crowder
显示剩余4条评论

0

使用 var 声明函数,它将在到达该行时执行。因此,在回调中调用它时,该函数尚未定义。为了能够使用它,请将其移动到 lineReader.on('line', function(){}) 之前,或者更好地像这样定义:

function dataCollector(folder_names, data) {
  /* Your function */
}

以这种方式进行,您的函数在脚本执行之前声明,因此当您到达回调时它已经存在。

你使用var声明函数,该声明将在到达该行时完成。因此,在回调中调用它时,函数尚未定义。不,那是不正确的,但可以理解为什么会这样认为。只有当readLine同步调用其回调时才会出现这种情况,但它并没有这样做。按照问题中的顺序放置事物是不好的实践,但是dataCollector将在调用回调时具有其值。 - T.J. Crowder
没错,可以参考 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/function 中的“函数声明提升”部分。不过,这里指出的问题是变量遮蔽。 - Max G.
叹气 是的,我知道函数声明是怎么工作的。我是说你关于 OP 代码的说法是不正确的。因为它是错误的。我也很清楚地解释了为什么它是错误的。 - T.J. Crowder
1
抱歉,我误读了你的帖子。我同意你的观点:)。但正如你指出的那样,我的观点是我认为函数声明的顺序不正确(但我可能错了)。 - Max G.
这并不是理想的,但也不是“错误”的,而且确实可以工作;当 OP 调用它时,函数确实已经被定义:https://jsfiddle.net/ef4s10dr/(对于像 Array#sort 使用的同步回调来说则不是这样。)OP 遇到的实际问题与此完全无关。 - T.J. Crowder

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接