【问题标题】:nodejs read file line by line and get its content at the endnodejs逐行读取文件并在最后获取其内容
【发布时间】:2018-09-21 19:37:47
【问题描述】:

我想使用 nodejs 逐行读取文件,然后在完成时将返回的结果作为 json 字符串。我试图这样做,但最后 console.log 打印 undefined 而不是列表。我得到了 list 和 promise 的结尾,但是如何将它返回给 main.js 中的调用函数?

我有我的 main.js 文件:

var fct = require('./romlist-parser');

console.log(fct.myfunction());

romlist-parser.js 有以下内容:

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

exports.myfunction = function() {

    var promise = new Promise(function(resolve,reject) {
        var rd = readline.createInterface({
            input: fs.createReadStream('Atari 2600.txt'),
            console: false
        });

        var games = [];

        rd.on('line', function(line) {
            var arr = line.split(";");
            games.push({name:arr[0], title:arr[1]});
        });

        rd.on('close', function() {
            var json = JSON.stringify(games);
            resolve(games);
        });

    });

    promise.then((resolveResult) => {
        console.log(resolveResult);
        return resolveResult;
    });
};

【问题讨论】:

  • 你能说几句你为什么使用readlinestreamPromise吗?一个简单的fs.readFile 不能在你的情况下完成这项工作吗?
  • 此 OP 中的第一个控制台日志打印函数返回的值。这是未定义的,因为该函数不返回任何内容。如果您随后没有看到记录的结果,则可能是由于读取错误(可能未找到文件)。您可以通过rd.on('error' ... 发现这一点

标签: node.js promise filereader es6-promise line-by-line


【解决方案1】:

试试这个:

exports.myfunction = function() {

    var promise = new Promise(function(resolve,reject) {

        var games = [];
        var rl = readline('./Atari 2600.txt'); // provide correct file path

        rl.on('line', function (line, lineCount, byteCount) {
            // console.log(lineCount, line, byteCount);
            var arr = line.split(";");
            games.push({name:arr[0], title:arr[1]});
        })
        .on('close', function() {
            var json = JSON.stringify(games);
            resolve(games); // resolve(json); may be?? 
        })
        .on('error', function (e) {
            console.log("error", e);
            // something went wrong
        });
    });

    promise.then((resolveResult) => {
        console.log(resolveResult);
        return resolveResult;
    });
};

附:此代码可以进一步改进,但为了简单起见,您的理解答案仅限于帖子中发布的样式/代码。否则它可以改变风格。

【讨论】:

  • 感谢 Zeeshan Hassan Memon 的回答,它很好地解决了我的问题。
【解决方案2】:

我会将设置和累积结果的变量移动到封闭范围内,然后,最重要的是,从创建它的函数返回承诺。所以……

exports.myfunction = function(filename) {
    let games = [];
    let rd = readline.createInterface({
        input: fs.createReadStream(filename),
        console: false
    });

    return new Promise(function(resolve,reject) {
        rd.on('line', function(line) {
            var arr = line.split(";");
            games.push({name:arr[0], title:arr[1]});
        });

        rd.on('close', function() {
            var json = JSON.stringify(games);
            resolve(games);
        });
        // on 'error' call reject(error)
    });
};

// then elsewhere

const fct = require('./romlist-parser');

function someFunction() {
    let promise = fct.myfunction('Atari 2600.txt');
    return promise.then(result => {
        console.log(result);
        return resolveResult
    });
}

【讨论】:

    【解决方案3】:

    我还需要处理大文件中的行的好方法。

    所以我做了这个。您可以轻松地在文件、流、字符串、缓冲区中逐行迭代

    它还支持反向模式!

    请尝试,如果喜欢,请给我一颗星!

    https://github.com/sharpart555/nexline

    const nl = nexline({
      input: fs.openSync(path_to_file, 'r'), // input can be file, stream, string and buffer
    });
    
    console.log(await nl.next()); // 'foo'
    console.log(await nl.next()); // 'bar'
    console.log(await nl.next()); // 'baz'
    console.log(await nl.next()); // null, If all data is read, then return null
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-23
    • 1970-01-01
    • 2018-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-02
    • 1970-01-01
    相关资源
    最近更新 更多