最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Use keypress to initiate action in node.js - Stack Overflow

programmeradmin3浏览0评论

I am using node.js v4.5

I wrote the function below to send repeated messages with a delay.

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);
    });
}

Instead of delay, I would like to activate the sending of messages using a keypress. Something like the function below.

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() )        
    ;
}

I am using node.js v4.5

I wrote the function below to send repeated messages with a delay.

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);
    });
}

Instead of delay, I would like to activate the sending of messages using a keypress. Something like the function below.

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() )        
    ;
}
Share Improve this question edited Sep 12, 2016 at 12:35 Bergi 666k161 gold badges1k silver badges1.5k bronze badges asked Sep 8, 2016 at 2:12 user6064424user6064424
Add a ment  | 

2 Answers 2

Reset to default 6 +50

You can put process.stdin in raw mode to access individual keystrokes.

Here's a standalone example:

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))

It will reject any keystroke that isn't Ctrl-B, but the code is easily modifiable if you don't want that behaviour (and just want to wait for the first Ctrl-B, for instance).

The value passed to keyPress is the decimal ASCII value of the key: Ctrl-A is 1, Ctrl-B is 2, a is 97, etc.

EDIT: as suggested by @mh-cbon in the ments, a better solution might be to use the keypress module.

Give this one a try. As mentioned above, using keypress makes it really simple. The key object in the code here tells you if ctrl or shift are pressed, as well as the character pressed. Unfortunately though, keypress doesn't seem to handle numbers or special characters.

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');
  }
}

And of course, in the sendMessage() function here, you could easily replace the log statements with something else more plex, make some async calls, call some other function, whatever. The process.stdin.pause() here causes the program to exit on ctrl-c, otherwise, the program would just keep running, blocking your interrupt signal, and you'd have to kill the process manually via mand line.

发布评论

评论列表(0)

  1. 暂无评论