Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
335 views
in Technique[技术] by (71.8m points)

node.js - How can I avoid overlapping readline and console.log in node

enter image description here

const re = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});
re.on("line", (order) => {
  if (!this.checkIsCorrectOrder(order)) {
    console.log("Wrong");
    return;
  }
  someFun(order)
}).on("close", () => {
  process.exit();
});

... ohter Asynchronous

let count = 0
setInterval(()=>{
    console.log(count++)
},1000)

I want to type while avoiding overlapping readline and console.log

how can i do that?

Is there any other way besides readline??? thanks!!

question from:https://stackoverflow.com/questions/65891912/how-can-i-avoid-overlapping-readline-and-console-log-in-node

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I am assuming that you mean you want to output to the terminal at the same time as you are writing commands into it, without it being spoiled?

Not quite done playing around with it, but so far this works for me:

var stdin = process.stdin;
var stdout = process.stdout;
var prompt = ">";
var current = "";

stdin.setRawMode(true);
stdin.setEncoding('utf8');
stdout.write(prompt);

stdin.on( 'data', function( key ){
    
    switch (key){
        case 'u001Bu005Bu0041'://up
        case 'u001Bu005Bu0043'://right
        case 'u001Bu005Bu0042'://down
        case 'u001Bu005Bu0044'://left  
        break;
        case 'u0003':
            process.exit();
        break;
        case 'u000d':    
            //RunCommands(current)      
            current = ""; 
            console.log("");
            stdout.write(prompt);
        break;
        case 'u007f':
            stdout.write("
x1b[K") ;
            current = current.slice(0, -1);
            stdout.write(prompt + current);
        break;
        default:
            stdout.write(key);
            current += key;
        break;
    }
});

function print(str){
    
    let totalCurrentLength = current.length + prompt.length;
    let lines = Math.ceil(totalCurrentLength / stdout.columns);
     
    for(i = 0; i < lines; i++){
        stdout.clearLine();
        stdout.write('u001Bu005Bu0041');
    }
    
    stdout.write('u001Bu005Bu0042');
    
    stdout.cursorTo(0)
    console.log(str);
    stdout.write(prompt + current);
}

var count = 0;
setInterval(() => {
    print("Test interference: " + count++)
}, 500);

Basically, I am keeping track of user inputs per keystroke and storing them in a string until the user presses return. Then I sent the "current" string to the place where I sort out and process all the possible command combinations.

I've been facing the same problem you have, I think, output disrupting input. So long as you use print() (which almost works like console.log, except you have to pass one argument, it does handle chalk and stuff tho) for the messages it should work ok.

Note, I disabled the arrow keys at the top, so that pressing the arrows doesn't move the cursor around and mess it all up.

'current' should be the string of commands you write in your terminal for the app, I made a function to deal with all the possible comand line functions.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...