使用按键触发node.js中的操作

10

我正在使用Node.js v4.5

我编写了下面的函数来延迟发送重复的消息。

function send_messages() {
    Promise.resolve()
        .then(() => send_msg() )
        .then(() => Delay(1000) )
        .then(() => send_msg() )
        .then(() => Delay(1000))
        .then(() => send_msg() )        
    ;
}

function Delay(duration) {
    return new Promise((resolve) => {
        setTimeout(() => resolve(), duration);
    });
}

我希望通过按键来激活消息的发送,而不是延迟。类似下面这个函数。

function send_messages_keystroke() {
    Promise.resolve()
        .then(() => send_msg() )
        .then(() => keyPress('ctrl-b') ) //Run subsequent line of code send_msg() if keystroke ctrl-b is pressed
        .then(() => send_msg() )
        .then(() => keyPress('ctrl-b') )
        .then(() => send_msg() )        
    ;
}
2个回答

6
您可以将process.stdin设置为原始模式,以访问单个按键。
以下是一个独立的示例:
function send_msg(msg) {
  console.log('Message:', msg);
}

// To map the `value` parameter to the required keystroke, see:
// http://academic.evergreen.edu/projects/biophysics/technotes/program/ascii_ctrl.htm
function keyPress(value) {
  return new Promise((resolve, reject) => {
    process.stdin.setRawMode(true);
    process.stdin.once('data', keystroke => {
      process.stdin.setRawMode(false);
      if (keystroke[0] === value) return resolve();
      return reject(Error('invalid keystroke'));
    });
  })
}

Promise.resolve()
  .then(() => send_msg('1'))
  .then(() => keyPress(2))
  .then(() => send_msg('2'))
  .then(() => keyPress(2))
  .then(() => send_msg('done'))
  .catch(e => console.error('Error', e))

它将拒绝任何不是Ctrl-B的按键,但如果您不想这样做(例如,只等待第一个Ctrl-B),则可以轻松修改代码。传递给keyPress的值是键的十进制ASCII值:Ctrl-A是1,Ctrl-B是2,a是97等。编辑:如@ mh-cbon在评论中建议的那样,更好的解决方案可能是使用keypress模块。

谢谢你的回答。已点赞。你是如何得到1代表Ctrl-A,2代表Ctrl-B,以及a代表97的值的? - user6064424
1
@user91579631 请查看此网页。_"Dec"_代码是您传递给keyPress的数字。对于常规字符,请参见此页面 - robertklep
1
你应该使用tootallnate的keypress模块 https://github.com/TooTallNate/keypress - user4466350
@mh-cbon 在回答之前我搜索了类似的内容,但没有找到任何有用的信息。这看起来非常适合这个任务! - robertklep
我修改了你的答案,但是我不太明白为什么如果我输入错误的密钥,承诺会挂起,这使得它无法使用。我绝对不精通 Promise。 - user4466350

1

尝试一下这个。如上所述,使用keypress使它变得非常简单。代码中的key对象告诉您是否按下ctrlshift,以及按下的字符。不幸的是,keypress似乎无法处理数字或特殊字符。

var keypress = require('keypress');

keypress(process.stdin);

process.stdin.on('keypress', function (ch, key) {
  console.log("here's the key object", key);

  shouldExit(key);
  if (key) {
    sendMessage(key);
  }
});

function shouldExit(key) {
  if (key && key.ctrl && key.name == 'c') {
    process.stdin.pause();
  }
}

function sendMessage(key) {
  switch(key.name) {
    case 'a';
        console.log('you typed a'); break;
    case 'b';
        console.log('you typed b'); break;
    default:
        console.log('bob is cool');
  }
}

当然,在这里的sendMessage()函数中,您可以轻松地将日志语句替换为更复杂的内容,进行一些异步调用,调用其他函数等等。此处的process.stdin.pause()会在按下ctrl-c时导致程序退出,否则,程序将继续运行,阻塞您的中断信号,并且您必须通过命令行手动终止该进程。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接