nodejs читает файл построчно и получает его содержимое в конце

Я хочу использовать nodejs для чтения файла построчно, а затем, когда он завершится, получить возвращаемый результат в виде строки json. Я пытался сделать так, но в конце console.log печатает undefined, а не список. Я получил список и конец промиса, но как вернуть его вызывающей функции в 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;
    });
};

person user1864255    schedule 11.04.2018    source источник
comment
Не могли бы вы сказать несколько слов о том, почему вы используете readline, stream и Promise? Разве простой fs.readFile не может справиться с этой задачей в вашем случае?   -  person RaphaMex    schedule 11.04.2018
comment
Первый журнал консоли в этой OP печатает значение, возвращаемое функцией. Это не определено, так как функция ничего не возвращает. Если впоследствии вы не видите записываемого результата, это может быть связано с ошибкой чтения (возможно, файл не найден). Вы можете узнать это с помощью rd.on('error' ...   -  person danh    schedule 11.04.2018


Ответы (3)


Попробуй это:

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;
    });
};

P.S. Этот код можно улучшить, но для простоты и вашего понимания ответ ограничен стилем/кодом, опубликованным в сообщении. В противном случае он может варьироваться от стиля к стилю.

person Zeeshan Hassan Memon    schedule 11.04.2018
comment
спасибо Zeeshan Hassan Memon за ваш ответ, он очень хорошо решил мою проблему. - person user1864255; 12.04.2018

Я бы переместил настройку и переменную, которая накапливает результаты, в охватывающую область, а затем, что наиболее важно, вернул бы обещание из функции, которая его создала. Так...

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
    });
}
person danh    schedule 11.04.2018

Мне также нужен был хороший способ обработки строки в большом файле.

Так что я сделал это. Вы можете легко перебирать строку за строкой в ​​файле, потоке, строке, буфере

Он также поддерживает реверсивный режим!

Пожалуйста, попробуйте, и если вам это нравится, дайте мне звезду!

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
person Jin    schedule 22.07.2019
comment
Проверьте это — npmjs.com/package/n-readlines - person Manohar Reddy Poreddy; 26.08.2020