【问题标题】:Node.js builtin module readline keeps reading lines after being closedNode.js 内置模块 readline 关闭后继续读取行
【发布时间】:2020-06-13 23:48:35
【问题描述】:

我有以下代码:

const fs = require("fs");
const {createInterface} = require("readline");
const {join} = require("path");
const {once} = require("events");

async function readMeta (path) {
    const meta = {};
    const rs = fs.createReadStream(path);
    const lineReader = createInterface({input: rs});

    let linesRead = 0;

    lineReader.on("line", line => {

        switch (linesRead) {
            case 0:
                meta.name = line;
                break;
            case 1:
                meta.tags = line.split(" ");
                break;
            case 2:
                meta.type = line;
                break;
            case 3:
                meta.id = +line;
        }

        if (++linesRead === 4) {
            lineReader.close();
        }
    });
    await once(lineReader, "close");
    rs.close();
    return meta;
}

它似乎正在工作,但是当line 事件触发时记录这些行会显示其他情况。在调用 lineReader.close() 后仍会触发该事件,从而导致读取整个文件。我不知道是什么原因造成的。我发现了一些显然可以完成这项工作的模块,但如果可能的话,我希望降低依赖关系。

【问题讨论】:

  • 更好await once(lineReader, 'end'); github.com/maleck13/readline/blob/master/readline.js#L51 文件可能不会关闭或关闭很快,但你的目标是在它结束阅读时捕捉。
  • 我不确定我明白你的意思,我的目标是让它停止阅读,我不想阅读整个文件。
  • lineReader.close();之后立即调用rs.close();怎么样,因为行阅读器从未关闭的读取流中获取输入
  • rslineReader 触发close 事件时被关闭。
  • please read" nodejs.org/api/readline.html#readline_rl_close Calling rl.close() does not immediately stop other events (including 'line') from being emitted by the readline.Interface instance. 这意味着您必须先关闭读取流

标签: node.js readline


【解决方案1】:

我建议不要处理和切换计数器,而是将行推入数组并防止在数组大小为 4 后进一步推入。

然后调用 close 和 after 将数组解构为必要的属性并返回包含它们的对象。

const fs = require("fs");
const {createInterface} = require("readline");
const {join} = require("path");
const {once} = require("events");

async function readMeta (path) {
    const meta = {};
    const rs = fs.createReadStream(path);
    const lineReader = createInterface({input: rs});

    const linesRead = [];

    lineReader.on("line", line => {
      if (linesRead.length === 4) {
        lineReader.close();
        rs.close();
        return;
      }
      linesRead.push(line.trim());
    });

    await once(lineReader, "close");
    delete rs;
    delete lineReader;

    const [name, tags, type, id] = linesRead;
    return {
      id,
      name,
      type,
      tags: tags.split(' '),
    };
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-11-20
    • 2020-05-27
    • 2019-03-25
    • 2016-08-01
    • 2018-10-12
    • 2023-03-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多