You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js读取多个Readable流时先创建的流读取中断如何解决?

问题根因

该问题是Node.js v14版本readline模块的已知缺陷:当创建多个绑定非TTY可读流的readline实例时,后一个实例通过for await...of完成读取后,会误触发前序所有readline实例的关闭逻辑。该缺陷在Node.js v16及以上正式版本中已被官方修复。

解决方案
  • 方案1:显式指定terminal: false配置(最适配v14版本的修复方式)
    创建所有readline实例时手动添加terminal: false参数,即可切断实例间的错误关联,修改后的代码如下:
import * as readline from 'readline';
import { Readable } from 'stream';

async function main() {
    const streamA = Readable.from('a');
    const readerA = readline.createInterface({
        input: streamA,
        crlfDelay: Infinity,
        terminal: false // 新增配置
    });

    var stopCase = true;
    if (stopCase) {
        const streamB = Readable.from('b');
        const readerB = readline.createInterface({
            input: streamB,
            crlfDelay: Infinity,
            terminal: false // 新增配置
        });

        console.log('readB');
        for await (const line of readerB) {
            console.log(line);
        }
    }
    console.log(`readerA.closed = ${'closed' in readerA}`);

    console.log('readA');
    for await (const line of readerA) {
        console.log(line);
    }
    console.log('success');
}
main();

修改后无论stopCase是否为true,readerA都不会被意外关闭,可正常输出所有内容。

  • 方案2:改用事件监听方式读取流
    避免使用for await...of迭代readline实例,改用监听line、close事件的方式读取内容,也可以规避该自动关闭bug,示例逻辑如下:
// 读取readerB的替代写法
readerB.on('line', line => {
  console.log(line)
})
readerB.on('close', () => {
  // 此处执行readerA的读取逻辑
})
  • 方案3:升级Node.js版本
    如果业务场景允许,直接升级到Node.js v16.0.0及以上版本,无需修改业务代码即可正常运行。

内容的提问来源于stack exchange,提问作者Takakiri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 11:27:03