Gaj*_*jus 8 ansi command-line-interface node.js
一个非常简单的程序,打印3行输出:
console.log('a');
console.log('b');
console.log('c');
Run Code Online (Sandbox Code Playgroud)
程序是否有一种方法可以在打印后删除最后一行?
console.log('a');
console.log('b');
console.log('c');
eraseLastLine();
console.log('C');
Run Code Online (Sandbox Code Playgroud)
会产生:
a
b
C
Run Code Online (Sandbox Code Playgroud)
Gaj*_*jus 16
简单的解决方案是不打印换行符(即不要使用console.log).
process.stdout.write打印线没有EOL字符.\r)字符返回到行的开头.\e[K从光标位置到行末清除所有字符.例:
process.stdout.write("000");
process.stdout.write("\n111");
process.stdout.write("\n222");
Run Code Online (Sandbox Code Playgroud)
对于这一行,输出将是:
000
111
222
Run Code Online (Sandbox Code Playgroud)
但是,如果您执行:
process.stdout.write("000");
process.stdout.write("\n111");
process.stdout.write("\n222");
process.stdout.write("\r\x1b[K")
process.stdout.write("333");
Run Code Online (Sandbox Code Playgroud)
输出是:
000
111
222\r\x1b[K
333
Run Code Online (Sandbox Code Playgroud)
但是,终端将显示:
000
111
333
Run Code Online (Sandbox Code Playgroud)
Ric*_*ber 12
以下对我有用:
process.stdout.clearLine();
process.stdout.cursorTo(0);
Run Code Online (Sandbox Code Playgroud)
方式一:
const clearLastLine = () => {
process.stdout.moveCursor(0, -1) // up one line
process.stdout.clearLine(1) // from cursor to end
}
Run Code Online (Sandbox Code Playgroud)
方式二:
const readline = require('readline')
const clearLastLine = () => {
readline.moveCursor(process.stdout, 0, -1) // up one line
readline.clearLine(process.stdout, 1) // from cursor to end
}
Run Code Online (Sandbox Code Playgroud)
方式3:
const ESC = '\x1b' // ASCII escape character
const CSI = ESC + '[' // control sequence introducer
const clearLastLine = () => {
process.stdout.write(CSI + 'A') // moves cursor up one line
process.stdout.write(CSI + 'K') // clears from cursor to line end
}
Run Code Online (Sandbox Code Playgroud)
方式一使用内置tty模块提供的方法。
方式二使用内置readline模块。
方式 3 使用ANSI 转义序列。
我通过查看log-update的源代码了解了ANSI 转义序列,这是我从dthree的答案中发现的。在做了更多的研究之后,我了解了内置和模块。readlinetty
通过阅读Node.js的源代码,我了解到方式 1 中使用的方法本质上是对方式 2 中使用的方法的包装,而方式 2 中使用的方法本质上是对方式 3 中使用的方法的包装。 所以每个方式最终在引擎盖下做基本相同的事情。上级到下级的方式我已经排序了。
我建议使用方式 1 替代方式 2 和方式 2 替代方式 3,主要是因为我认为方式 1 比方式 2 代码更少、更清晰(因此更具可读性),而方式 2 代码更少、更清晰(因此更多可读)而不是方式 3,并且通过使用较低级别的方式实现的性能改进(如果有)可能可以忽略不计。但是,我认为方式 3 避免加载内置readline模块。
这个解决方案(每一种方式)假设您的光标在程序调用之前位于空行的开头clearLastLine()。正如Gajus在他的回答中所述,如果您的光标位于最后一行的末尾,则解决方案会更简单。那么您可以使用process.stdout.write()(而不是console.log())来打印没有尾随换行符的最后一行吗?
或者,如果您不需要首先打印最后一行,则解决方案甚至更简单。所有这些对标准输出的修补都是代码异味吗?你能重新设计你的代码,这样最后一行就不会被打印出来吗?
在我的情况下,我正在测试我编写的调用的帮助函数console.error(),并且我不希望记录的错误消息显示在我的测试输出中。因此,不是让我的辅助函数调用console.error(),我可以让它抛出一个错误(或者只是返回一个错误代码和/或消息或一个布尔值)。然后,console.error()如果我的辅助函数抛出错误(或返回错误代码和/或消息或false),则调用我的辅助函数的主程序可以调用。或者我可以将一个布尔标志参数传递给我的辅助函数,告诉它是否记录错误。或者我可以重定向 stderr,或模拟globalconsole或stub console.error()等。
如果您想清除写入 的最后三行system.stdout,您可以执行以下操作:
const clearLastLines = (count) => {
process.stdout.moveCursor(0, -count)
process.stdout.clearScreenDown()
}
clearLastLines(3)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6667 次 |
| 最近记录: |