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

如何正确终止Node.js readline promise的question方法?

使用node:readline/promises处理SIGINT/Ctrl+D导致的未解决顶级await问题

问题场景

在Node.js v22.2.0的ES模块环境中,使用node:readline/promises的rl.question()等待用户输入时,若用户通过SIGINT(Ctrl+C)或Ctrl+D终止操作,会触发「未解决顶级await」警告——因为rl.question()返回的Promise未被妥善拒绝或完成。

问题代码

import * as readline from 'node:readline/promises';

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

const answer = await rl.question('>>> ');

触发的警告信息

Warning: Detected unsettled top-level await at file:///foo/bar/test.js:xx
const answer = await rl.question('>>> ');

解决方案:妥善处理中断与关闭事件

通过Promise.race让用户输入Promise和中断处理Promise竞争,在触发中断或流关闭时主动拒绝Promise,确保顶级await能被正确处理。

import * as readline from 'node:readline/promises';

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

// 封装中断处理逻辑为Promise
const handleInterruption = new Promise((_, reject) => {
  // 监听SIGINT信号(Ctrl+C)
  process.once('SIGINT', () => {
    console.log('\n用户通过Ctrl+C中断输入');
    rl.close();
    reject(new Error('输入操作被中断'));
  });

  // 监听readline接口的close事件(比如Ctrl+D触发)
  rl.once('close', () => {
    console.log('输入流已关闭(Ctrl+D)');
    reject(new Error('输入流终止'));
  });
});

try {
  // 同时等待用户输入或中断事件
  const answer = await Promise.race([rl.question('>>> '), handleInterruption]);
  console.log(`你输入的内容是: ${answer}`);
} catch (err) {
  console.error('处理提示:', err.message);
} finally {
  // 确保readline接口被关闭
  if (!rl.closed) {
    rl.close();
  }
}

思路说明

这个方案和你提供的非Promise版readline思路一致:通过监听中断信号和流关闭事件,主动终止未完成的Promise。区别在于利用Promise.race简化了逻辑,无需手动维护reject函数的引用,同时统一了SIGINT和Ctrl+D两种场景的处理。

非Promise版参考代码(你提供的实现)

import * as readline from 'node:readline';

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

let rej = () => {};
rl.on('close', () => {
  console.log('closing');
  rej();
});

const answer = await new Promise((r, j) => {
  rej = j;
  rl.question('>>> ', r);
}).catch(() => console.error('interrupted'));

内容的提问来源于stack exchange,提问作者W. Smith

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 07:22:46