我还没有看到一个全面的答案。特别是,process.stdin.destroy()
如果您需要多次按键,则使用的答案会排除调用两次的函数。那些不调用的会process.stdin.off(...)
继续处理按键。即使在程序完成后,那些不调用process.stdin.pause()
的进程也会保持活动状态。
我相信以下功能非常彻底。不带参数调用,它显示一条"Press any key to continue..."
消息并等待用户按任意键。该message
参数覆盖默认消息。该keys
参数允许您侦听特定键,如果按下其他键,消息将重复。keys
除非参数是大小写混合的,否则按下的接受键不区分大小写。
返回值是Promise
用户按下的键(大小写调整为不区分大小写keys
)。如果他们按 ,则承诺将被拒绝CTRL-c
。
function keyPress(message, keys) {
const _message = message || "Press any key to continue...";
const _keys = keys || "";
return new Promise(function (resolve, reject) {
const caseSensitive = _keys.toLowerCase() !== _keys && _keys.toUpperCase() !== _keys;
process.stdout.write(_message);
function keyListener(buffer) {
let key = buffer.toString();
if (key.charCodeAt(0) === 3) {
process.stdin.setRawMode(false);
process.stdin.off('data', keyListener);
process.stdin.pause();
// process.exit(0); // Exit process if you prefer.
reject(key.charCodeAt(0));
}
const index = caseSensitive ? _keys.indexOf(key) : _keys.toLowerCase().indexOf(key.toLowerCase());
if (_keys && index < 0) {
process.stdout.write(key);
process.stdout.write("\n");
process.stdout.write(_message);
return;
}
process.stdin.setRawMode(false);
process.stdin.off('data', keyListener);
process.stdin.pause();
if (index >= 0) {
key = _keys.charAt(index);
process.stdout.write(key);
}
process.stdout.write("\n");
resolve(key);
}
process.stdin.resume();
process.stdin.setRawMode(true);
process.stdin.on('data', keyListener);
});
}
示例 1:显示Press any key to continue...
消息,等待任何按键。
await keyPress();
示例 2:显示Process data? (Y|N):
消息,等待用户按y
、n
、Y
或N
。如果按下其他键,则重复该消息。无论大小写如何,answer
都将是'y'
或。'n'
const answer = await keyPress("Process data? (Y|N): ", "yn");