[英]press any key to continue in nodejs
我需要一个函数来暂停脚本的执行,直到按下一个键。 我试过:
var stdin = process.openStdin();
require('tty').setRawMode(true);
stdin.on('keypress', function (chunk, key) {
process.stdout.write('Get Chunk: ' + chunk + '\n');
if (key && key.ctrl && key.name == 'c') process.exit();
});
但它只是在听按键而没有任何反应。 程序不会继续执行。
如何暂停执行?
在 node.js 7.6 及更高版本中,您可以执行以下操作:
const keypress = async () => {
process.stdin.setRawMode(true)
return new Promise(resolve => process.stdin.once('data', () => {
process.stdin.setRawMode(false)
resolve()
}))
}
;(async () => {
console.log('program started, press any key to continue')
await keypress()
console.log('program still running, press any key to continue')
await keypress()
console.log('bye')
})().then(process.exit)
或者,如果您希望 CTRL-C 退出程序但任何其他键继续正常执行,那么您可以用此函数替换上面的“keypress”函数:
const keypress = async () => {
process.stdin.setRawMode(true)
return new Promise(resolve => process.stdin.once('data', data => {
const byteArray = [...data]
if (byteArray.length > 0 && byteArray[0] === 3) {
console.log('^C')
process.exit(1)
}
process.stdin.setRawMode(false)
resolve()
}))
}
对我有用:
console.log('Press any key to exit');
process.stdin.setRawMode(true);
process.stdin.resume();
process.stdin.on('data', process.exit.bind(process, 0));
如果您不想退出该过程,此代码段可以完成这项工作:
console.log('Press any key to continue.');
process.stdin.once('data', function () {
continueDoingStuff();
});
它是异步的,所以不能按原样在循环内工作——如果你使用的是 Node 7,你可以将它包装在一个 promise 中并使用async/await
。
接受的解决方案是异步等待按键事件然后退出,并不是真正的“按任意键继续”的解决方案。
我在编写一些 nodejs shell 脚本时需要暂停。 我最终将 child_process 的 spawnSync 与 shell 命令“read”一起使用。
这将基本上暂停脚本,当您按 Enter 时,它将继续。 很像 windows 中的 pause 命令。
require('child_process').spawnSync("read _ ", {shell: true, stdio: [0, 1, 2]});
希望这会有所帮助。
有一个包: press-any-key
这是一个例子:
const pressAnyKey = require('press-any-key');
pressAnyKey("Press any key to resolve, or CTRL+C to reject", {
ctrlC: "reject"
})
.then(() => {
console.log('You pressed any key')
})
.catch(() => {
console.log('You pressed CTRL+C')
})
它在 W10 中运行没有问题。
var fs = require("fs")
var fd = fs.openSync("/dev/stdin", "rs")
fs.readSync(fd, new Buffer(1), 0, 1)
fs.closeSync(fd)
const fs = require('fs');
process.stdin.setRawMode(true);
fs.readSync(0, Buffer.alloc(1), 0, 1);
60% 的时间,它每次都有效。
聚会迟到了,但这是我的hacky解决方案。 基本上 goDoWork 在承诺解决之前不会运行,这只会在您按下 Enter 时发生。
let resolv = null;
const promise = new Promise((resolve, reject) => {
resolv = resolve;
})
var stdin = process.openStdin();
console.log('Press enter to continue');
stdin.on('data', () => {
resolv();
console.log("Key pressed");
});
promise.then(goDoWork);
const readline = require('readline');
readline.emitKeypressEvents(process.stdin);
process.stdin.setRawMode(true);
process.stdin.on('keypress', (str, key) => {
if (key.ctrl && key.name === 'c') {
process.exit();
} else {
console.log(`You pressed the "${str}" key`);
console.log();
console.log(key);
console.log();
}
});
console.log('Press any key...');
在我的情况下,我通过将setRawMode
为 false 来解决它,如下所示:
setRawMode(value) {
if (process.stdin.isTTY) {
process.stdin.setRawMode(value);
}
}
confirm(settings) {
logUtils.log(logService.createConfirmSettingsTemplate(settings));
readline.emitKeypressEvents(process.stdin);
this.setRawMode(true);
return new Promise((resolve, reject) => {
try {
process.stdin.on('keypress', (chunk, key) => {
if (chunk) { }
resolve(key && key.name === 'y');
this.setRawMode(false);
});
}
catch (error) {
this.setRawMode(false);
reject(false);
}
}).catch(this.setRawMode(false));
}
我还没有看到一个全面的答案。 特别是,如果您需要多次按键,使用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):
Process data? (Y|N):
消息,等待用户按y
、 n
、 Y
或N
。 如果按下其他键,则重复该消息。 answer
将是'y'
或'n'
,无论按下大小写。
const answer = await keyPress("Process data? (Y|N): ", "yn");
按任意键继续
function pressAnyKey(msg = 'Press any key to continue') {
return new Promise((resolve) => {
console.log(msg || 'Press any key to continue');
process.stdin.setRawMode(true);
process.stdin.resume();
process.stdin.on('data', () => {
process.stdin.destroy();
resolve();
});
});
}
(async () => {
await pressAnyKey();
console.log('hello');
})();
// timeout version
function pressAnyKey(msg = 'Press any key to continue', timeout = 3000) {
return new Promise((resolve) => {
let handler = null;
const end = () => {
process.stdin.destroy();
if (handler) clearTimeout(handler);
resolve();
}
console.log(msg || 'Press any key to continue');
process.stdin.setRawMode(true);
process.stdin.resume();
process.stdin.on('data', end);
handler = setTimeout(end, Math.max(1, timeout));
});
}
谢谢@vkurchatkin
我实际上制作了一个名为paktc
的 npm 包,它将帮助您解决这个问题。 如果安装软件包:
> npm install paktc
然后你会像这样使用它:
// your console application code here...
require('paktc') // Press any key to continue...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.