Асинхронное чтение файла с чтением разного количества строк каждый раз, без остановки - PullRequest
0 голосов
/ 24 июня 2019

Я построил простую асинхронную реализацию модуля readlines, встроенного в nodejs, который является просто оболочкой для самого модуля на основе событий. Код ниже;

const readline = require('readline');

module.exports = {
  createInterface: args => {
    let self = {
      interface: readline.createInterface(args),
      readLine: () => new Promise((succ, fail) => {
        if (self.interface === null) {
          succ(null);
        } else {
          self.interface.once('line', succ);
        }
      }),
      hasLine: () => self.interface !== null
    };
    self.interface.on('close', () => {
      self.interface = null;
    });
    return self;
  }
}

В идеале, я бы использовал это так, в коде, подобном этому;

const readline = require("./async-readline");

let filename = "bar.txt";

let linereader = readline.createInterface({
  input: fs.createReadStream(filename)
});

let lines = 0;
while (linereader.hasLine()) {
  let line = await linereader.readLine();
  lines++;
  console.log(lines);
}

console.log("Finished");

Тем не менее, я наблюдал некоторое странное и неожиданное поведение с этой асинхронной оболочкой. Во-первых, он не может распознать, когда файл заканчивается, и просто зависает, как только достигает последней строки, никогда не печатая «Завершено». И, кроме того, когда входной файл большой, скажем, несколько тысяч строк, он всегда отключается на несколько строк и не может полностью прочитать весь файл перед остановкой. в строковом файле 2000+ он может быть отключен на 20-40 строк. Если я брошу оператор print в слушатель .on('close', я вижу, что он срабатывает; однако программа по-прежнему не распознает, что у нее больше не должно быть строк для чтения.

1 Ответ

1 голос
/ 24 июня 2019

Кажется, что в nodejs v11.7 интерфейс readline получил асинхронную итераторную функциональность и может быть просто зациклен с помощью цикла for await ... of;

const rl = readline.createInterface({
  input: fs.createReadStream(filename);
});

for await (const line of rl) {
  console.log(line)
}

Как получить синхронную readline или "смоделировать" ее, используя async, в nodejs?

...