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

使用Readline异步读取标准输入遇异步执行问题求助

问题描述

我正在查看O'Reilly书籍《JavaScript权威指南》中的一个示例并尝试修改。原示例使用输入重定向(node charfreq.js < input.txt)时运行正常,但我希望改成让用户在Windows命令行手动输入内容,按下Ctrl+Z(Windows下结束输入的快捷键,按后回车)后脚本再继续执行。尝试用readline替代process.stdin时,搞不定异步逻辑。

原始代码:

async function histogramFromStdin() {
    process.stdin.setEncoding("utf-8"); // 读取Unicode字符串而非字节
    let histogram = new Histogram();
    for await (let chunk of process.stdin) {
        histogram.add(chunk);
    }

    return histogram;
}

// 程序主逻辑:从标准输入生成直方图并打印
histogramFromStdin().then(histogram => { console.log(histogram.toString()); });

我的尝试:
问题在于console.log(histogram.toString());会立即执行,此时histogram还是未定义状态,不知道该在何处添加await。

async function histogramFromStdin() {
    var readline = require('readline');
    process.stdin.setEncoding('utf-8');
    let histogram = new Histogram();

    var rl = readline.createInterface({ input: process.stdin, output: process.stdout });
    rl.setPrompt('> ');
    rl.prompt();
    rl.on('line', function (chunk) { histogram.add(chunk); rl.prompt(); });
    rl.on('close', function () { console.log('Input has closed'); return histogram; });
}

// 程序主逻辑:从标准输入生成直方图并打印
histogramFromStdin().then(histogram => { console.log(histogram.toString()); });
解决方案

核心是把readline的回调逻辑包装成Promise,让异步函数能等待输入完成后再返回结果:

async function histogramFromStdin() {
    const readline = require('readline');
    process.stdin.setEncoding('utf-8');
    let histogram = new Histogram();

    // 用Promise包裹readline的事件逻辑
    return new Promise((resolve) => {
        const rl = readline.createInterface({ 
            input: process.stdin, 
            output: process.stdout 
        });
        rl.setPrompt('> ');
        rl.prompt();
        
        // 处理每一行输入
        rl.on('line', (chunk) => { 
            histogram.add(chunk); 
            rl.prompt(); 
        });
        
        // 输入结束时返回直方图
        rl.on('close', () => { 
            console.log('输入已结束');
            resolve(histogram);
        });
    });
}

// 主程序逻辑
histogramFromStdin().then(histogram => { 
    console.log(histogram.toString()); 
});

说明

  • 原代码中histogramFromStdin是async函数,但内部readline基于回调,函数会直接返回undefined,导致then里拿到的是未定义的结果。
  • 用Promise包裹后,当close事件触发时,通过resolve(histogram)把最终结果传递出去,async函数会等待这个Promise完成,返回正确的Histogram实例。
  • Windows命令行中,按下Ctrl+Z再回车就能触发close事件,结束输入。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 04:15:21