What I am trying to accomplish is to have an asynchronous function (works with async/await
syntax) that captures a single keypress, and then the control flow of the program resumes normally after that point. I have accomplished this using readline
and process.stdin
, however how do I stop the application from listening to keypress once started?
import readline from 'readline';
import os from 'os'
const eol = os.EOL;
readline.emitKeypressEvents(process.stdin);
process.stdin.setRawMode(true);
function awaitKeypress() {
const promise = new Promise<string>( (resolve, reject) => {
// need to stop listening here after a keypress is captured
process.stdin.on('keypress', (str, key) => {
console.log('Keypress<<', process.stdin)
resolve('--key-pressed--')
})
} )
return promise
}
async function main() {
console.log('Press a key');
const response = await awaitKeypress()
console.log("Flow resumed, response is:", response)
}
main()
I get the expected output
Press a key
Keypress<<
Flow resumed, response is: --key-pressed--
However each keypress subsequent results in the callback specified in stdin.on
being called.
Press a key
Keypress<<
Flow resumed, response is: --key-pressed--
Keypress<<
Keypress<<
Keypress<<
I want to stop listening for keypresses and resume normal application behavior after I have captured a single keypress.
Use removeListener
.
import readline from 'readline';
import os from 'os'
const eol = os.EOL;
readline.emitKeypressEvents(process.stdin);
process.stdin.setRawMode(true);
/**
* Wait for a keypress
* @returns Promise
*/
export async function keypress( key?:string ) {
process.stdin.setRawMode(true);
const promise = new Promise<KeypressEvent>( (resolve, reject) => {
const listener = (str, keypressEvent: KeypressEvent) => {
if ( keypressEvent.ctrl === true && keypressEvent.name === 'c' ) {
process.stdin.removeListener('keypress', listener)
process.stdin.setRawMode(false);
process.exit()
}
if ( key === undefined || key === keypressEvent.name ) {
/* here */
process.stdin.removeListener('keypress', listener)
process.stdin.setRawMode(false);
resolve(keypressEvent)
}
}
process.stdin.on('keypress', listener )
} )
return promise
}