NodeJS 中的 Readline 正在绘制不需要的线条

Posted

技术标签:

【中文标题】NodeJS 中的 Readline 正在绘制不需要的线条【英文标题】:Readline in NodeJS is drawing unwanted lines 【发布时间】:2017-05-09 22:24:03 【问题描述】:

我有以下问题,我在终端窗口中绘制一个 ASCII 字符,然后将光标移动到另一个位置并使用以下代码重复该过程。

const readline = require('readline');

//
//  Set the direction of the cursor
//
let dirrection_y = true;
let dirrection_x = true;

//
//  Set the initial position of the cursor
//
let position_x = 0;
let position_y = 0;

//
//  Get the terminal window size
//
let window_x = process.stdout.columns;
let window_y = process.stdout.rows;

//
//  Set the cursor to the top left corner of the terminal window so we can clear
//  the terminal screen
//
readline.cursorTo(process.stdout, position_x, position_y)

//
//  Clear everything on the screen so we have a clean template to draw on.
//
readline.clearScreenDown(process.stdout)

//
//  Create the interface so we can use it to for example write on the console.
//
let rl = readline.createInterface(
    input: process.stdin,
    output: process.stdout,
);

//
//  React to CTR+C so we can close the app, and potentially do something before
//  closing the app.
//
rl.on('close', function() 

    process.exit(0);

);

//
//  Start the main loop
//
draw();

//
//  The main loop that moves the cursor around the screen.
//
function draw()

    setTimeout(function() 

        //
        //  1.  Move the cursor up or down
        //
        dirrection_y ? position_y++ : position_y--

        //
        //  2.  When we reach the bottom of the terminal window, we switch
        //      direction from down, to up.
        //
        if(position_y == window_y)
        
            //
            //  1.  Switch the direction to go up
            //
            dirrection_y = false

            //
            //  2.  Move the next column or previous one depending on the
            //      direction.
            //
            dirrection_x ? position_x++ : position_x--
        

        //
        //  3.  When we reach the top of the terminal screen, switch direction
        //      again
        //
        if(position_y < 0)
        
            //
            //  1.  Switch the direction to go down
            //
            dirrection_y = true

            //
            //  2.  Move the next column or previous one depending on the
            //      direction.
            //
            dirrection_x ? position_x++ : position_x--
        

        //
        //  4.  When we reach the far right of the terminal screen we switch
        //      direction from 'to right', to 'to left'
        //
        if(position_x == window_x)  dirrection_x = false 

        //
        //  5.  When we reach the far left (beginning) of the terminal window
        //      we switch direction again.
        //
        if(position_x == 0)  dirrection_x = true 

        //
        //  6.  Write on char on the terminal screen.
        //
        rl.write('█');

        //
        //  7. Move the cursor to the next position
        //
        readline.cursorTo(process.stdout, position_x, position_y)

        //
        //  8.  Restart the loop.
        //
        draw();

    , 100)

一切都很顺利,直到屏幕上出现一条我没有画出的完整线条,如下图所示

如果我最终让应用继续运行,整个屏幕将填满覆盖我正在绘制的内容的线条。

问题

我不相信我在画那些线,如果这是真的,终端窗口会发生什么?

技术安全

macOS Terminal 和 iTerm 有同样的问题 NodeJS v6.40

【问题讨论】:

【参考方案1】:

在查看 readline 的源代码时,我相信 an old hack 他们添加以纠正某些选项卡行为仍然会导致 this current line 出现问题。每当在 0 处检测到光标位置 cols (可能是源中的另一个错误),它就会发出一个 refreshLine --- 抛出一个提示。 docs 表示“rl.write() 方法会将数据写入 readline 接口的输入,就好像它是由用户提供的一样。”因此提示会将您的所有输入输出回给您。

我找不到源内解决方法,但您可以修改接口的源代码。在你的const readline = require('readline'); 之后添加这个 sn-p 来解决问题。

readline.Interface.prototype._insertString = function(c) 
  if (this.cursor < this.line.length) 
    var beg = this.line.slice(0, this.cursor);
    var end = this.line.slice(this.cursor, this.line.length);
    this.line = beg + c + end;
    this.cursor += c.length;
    this._refreshLine();
   else 
    this.line += c;
    this.cursor += c.length;
    this.output.write(c);
    this._moveCursor(0);
  
;

【讨论】:

太棒了,你的解释是正确的,代码刚刚工作!非常感谢:) 出于好奇,您为什么不通过拉取请求来解决此问题,并将_insertString 替换为您刚刚在此处写的内容? @DavidGatti 是的,好主意——我正在努力——我只需要让标签修复案例和你的案例都值得。

以上是关于NodeJS 中的 Readline 正在绘制不需要的线条的主要内容,如果未能解决你的问题,请参考以下文章

如何在nodejs中产生按键检测?

如何在nodejs中获得同步readline,或使用异步“模拟”它?

nodejs 读取文件中的几行

nodejs 读取文件中的几行

nodejs 读取文件中的几行

相当于 c++ 中的 Console.ReadLine()