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

为何将JavaScript readline的question方法包装进Promise会读取多行?

Node.js readline.question 文件重定向时的行为差异原因

问题场景

使用readline模块编写的代码,手动在命令行输入时能正常逐行读取并添加行号,但通过文件重定向(如node testReadline.mjs < the_file.txt)输入时,会一次性读取整个文件内容,输出不符合预期。

预期输出

Next line, please: File line 1
1       File line 1
Next line, please: File line 2
2       File line 2
Next line, please: File line 3
3       File line 3
Next line, please: File line 4
4       File line 4
Next line, please: Input stream closed.

实际输出

Next line, please: File line 1
File line 2
File line 3
File line 4
1       File line 1
Next line, please: Input stream closed.

异步await实现代码(不符合预期)

import * as readline from 'node:readline';

const io = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
});

io.on('close', () => { console.log("Input stream closed.") });

let questionWrapper = (prompt) => {
    return new Promise((resolve, reject) => {
        io.question(prompt, (line) => {
            resolve(line)
        });
    });
}

let printLine_await = async () => {
    let line_num = 1;
    while (true) {
        let line = await questionWrapper('Next line, please: ');
        console.log(`${line_num}\t${line}`)
        line_num++;
    }
}

printLine_await(1)

回调实现代码(符合预期)

let printLine_callback = (line_num) => {
    io.question('Next line, please: ', (line) => {
        console.log(`${line_num}\t${line}`)
        printLine_callback(line_num + 1)
    })
}

原因解析

异步await版本异常的核心原因

  1. 文件输入的缓冲特性:文件重定向输入时,Node.js会一次性把整个文件内容加载到标准输入缓冲区,而非手动输入时的逐行触发。
  2. question的事件监听逻辑:io.question()执行时,会先输出提示,然后监听输入流的line事件。但缓冲区已有多行内容时,第一个question只会捕获第一行,剩余行仍在缓冲区中。
  3. 异步时序的间隙问题:await会暂停循环,等待第一个Promise完成。这期间,输入流中剩余的内容会直接被输出到终端(因为readline没有暂停输入流),不会被后续的question调用捕获。当缓冲区内容全部输出后,输入流关闭,循环直接终止。

回调版本正常的原因

回调实现中,每处理完一行后才会发起下一次question调用。每次question都会重新绑定line事件监听,此时缓冲区中的下一行会被当前question正确捕获,不会直接输出到终端,从而实现逐行处理的效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 12:35:21