为什么我的全局数组索引在我需要时未定义?

时间:2015-10-28 17:58:41

标签: javascript node.js fs

我有以下代码用于打开文件,逐行读取,并将每行推送到数组。在将它推送到数组之前,我能够控制它.log所以我知道它在那个阶段有一个值作为一行。但是我之后无法将它作为数组元素的console.log。我认为这与范围有关,但我不明白为什么它根本不起作用 - 它只是记录为“未定义”。

var fs = require ("fs");

var lines = [];

function readLines(input, func)
{
    var remaining = '';

    input.on('data', function(data)
    {
        remaining +=data;

        var index = remaining.indexOf('\n');

        while(index > -1)
        {
            var line = remaining.substring(0, index);
            remaining = remaining.substring(index + 1);

            func(line);

            index = remaining.indexOf('\n');
        }
    });

    input.on('end', function()
    {
        if(remaining.length > 0)
        {
            func(remaining);
        }
    });
}

function func(data)
{
    console.log ("line : " + data);
    lines.push(data);
}

var input = fs.createReadStream('testing.csv');
readLines(input, func);

console.log(lines[0]);

2 个答案:

答案 0 :(得分:2)

你可能想在函数完成后检查 - 它是异步的,所以你的console.log(lines [0])将在它读取数据之前执行(最有可能)

尝试添加:

input.on('end', function(){
    if(remaining.length > 0)
    {
        func(remaining);
    }
    console.log(lines[0]);
}

readLines()

答案 1 :(得分:1)

嗯,这与javascript的异步特性有关。

您正在创建一个读取流

  

fs.createReadStream( 'testing.csv');

然后,你正在听它的事件:

  

input.on('data',function(data)
      input.on('end',function()

但是,这些事件中的内容会在触发时执行。

在您的代码中,您有:

var input = fs.createReadStream('testing.csv');
readLines(input, func);

// You are trying to access the line at position zero, 
// when it might not been set yet, 
// since the events might have not been triggered yet.
console.log(lines[0]);

一旦readLines完成,您将需要确保使用这些行尝试将结束侦听器设置在readLines函数之外,如下所示:

var input = fs.createReadStream('testing.csv');
readLines(input, func);

//console.log(lines[0]);

input.on('end', function(){
    console.log(lines[0]);
});

Javascript是一个不同的野兽,它有自己的成语和范例如何为它编程,你可能想要阅读关于如何更好地构建代码以使其异步性质的最佳实践。