2016-09-08 12 views
9

Tôi đang sử dụng node.js v4.5Sử dụng nhấn phím để bắt đầu hành động trong node.js

Tôi đã viết hàm bên dưới để gửi tin nhắn lặp lại với độ trễ.

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

Thay vì chậm trễ, tôi muốn kích hoạt việc gửi tin nhắn bằng cách nhấn phím. Một cái gì đó giống như chức năng dưới đây.

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

Trả lời

6

Bạn có thể đặt process.stdin ở chế độ thô để truy cập các lần nhấn phím riêng.

Dưới đây là một ví dụ độc lập:

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

Nó sẽ từ chối bất kỳ tổ hợp phím đó không phải là Ctrl-B, nhưng mã có thể dễ dàng sửa đổi nếu bạn không muốn hành vi đó (và chỉ muốn hãy chờ Ctrl-B đầu tiên, ví dụ).

Giá trị truyền cho keyPress là giá trị ASCII thập phân của phím: Ctrl-A là 1, Ctrl-B là 2, một là 97 vv

EDIT: theo gợi ý của @ mh-cbon trong các bình luận, một giải pháp tốt hơn có thể là sử dụng mô-đun keypress.

+0

Cảm ơn câu trả lời. Được thăng hạng. Làm cách nào để bạn nhận được giá trị 1 là Ctrl-A, 2 -> Ctrl-B và a -> 97? –

+1

@ user91579631 xem [trang web này] (http://academic.evergreen.edu/projects/biophysics/technotes/program/ascii_ctrl.htm). Mã _ "Dec" là số bạn chuyển tới 'keyPress'. Đối với các ký tự thông thường, xem [trang này] (http://academic.evergreen.edu/projects/biophysics/technotes/program/ascii_std.htm). – robertklep

+1

bạn nên sử dụng mô-đun bấm phím tootallnate https://github.com/TooTallNate/keypress –

1

Hãy thử cái này. Như đã đề cập ở trên, sử dụng nhấn phím làm cho nó thực sự đơn giản. Đối tượng key trong mã ở đây cho bạn biết nếu nhấn ctrl hoặc shift cũng như ký tự được nhấn. Thật không may, mặc dù, keypress dường như không xử lý số hoặc ký tự đặc biệt.

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

Và dĩ nhiên, trong sendMessage() chức năng ở đây, bạn có thể dễ dàng thay thế những điều khoản đăng nhập với cái gì khác phức tạp hơn, làm cho một số cuộc gọi async, gọi một số chức năng khác, bất cứ điều gì. Các process.stdin.pause() ở đây gây ra các chương trình để thoát ra trên ctrl-c, nếu không, chương trình sẽ chỉ tiếp tục chạy, chặn tín hiệu ngắt của bạn, và bạn sẽ phải giết quá trình bằng tay thông qua dòng lệnh.

Các vấn đề liên quan