更新控制台中打印的文本

Update text printed in console

提问人:Devix 提问时间:7/24/2023 更新时间:7/24/2023 访问量:18

问:

我正在 ts 中创建一个 CLI 程序,我的命令正在将进度写入控制台。我想通过避免写几行这样的行来使它更漂亮:

Starting microservice api-gateway 🔄
Microservice api-gateway started ✅

Starting microservice Agenda 🔄
Microservice Agenda started ✅

Starting microservice Device 🔄
Microservice Device started ✅
...

只需重写第一行即可修改表情符号:

Starting microservice api-gateway 🔄 -> Starting microservice api-gateway ✅
Starting microservice Agenda 🔄 -> Starting microservice Agenda ✅
Starting microservice Device 🔄 -> Starting microservice Device ✅
...

我设法实现了第一个版本:

process.stdout.write("Starting microservice api-gateway 🔄")
# make something
process.stdout.moveCursor(0,-1)
process.stdout.write("✅")

此代码可以完美运行,但存在一个问题:在两个函数之间不应将任何其他内容写入控制台。

因此,我设法实现了第二个版本来处理这个问题。此版本使用全局变量来存储打印到表中的每个日志:

writeLog.ts(英语:writeLog.ts)

/**
 * Writes a log to the console and returns the index of the log
 * @param log The log to write
 * @return {number} The index of the log
 */
export default function writeLog(log: string): number {
    process.stdout.write(log);

    let newLog: Log = {
        log: log,
        cursorPos: {
            x: process.stdout.rows,
            y: process.stdout.columns
        }
    };

    let index = global.logs.push(newLog);
    process.stdout.write("\n");
    return index - 1;
}

重写日志.ts

/**
 * rewrite a log in the console
 * @param index The index of the log
 * @param log The new log
 */
export default function rewriteLog(index: number, log: string) {
    let row = global.logs.length - index;
    let col = global.logs[index].cursorPos.y;

    let pos = {
        row: process.stdout.rows,
        col: process.stdout.columns
    }

    process.stdout.moveCursor(-col, -row);
    process.stdout.clearLine(1);
    process.stdout.write(log + "\n");


    process.stdout.moveCursor(
        pos.col - col,
        pos.row - row
    );

    global.logs[index].log = log;
}

这两个函数允许我编写日志并重写它。它可以正常工作,但有两种情况除外:异步调用它们,或者调用速度太快。

对于太快的调用,我的研究将我引向包含回调参数的 AND 函数,这意味着该函数不是同步的,因此我有可能在第一个完成写入甚至开始之前再次移动光标。process.stdout.write()process.stdout.moveCursor()

对于第二个问题,它几乎是一样的,只有一个光标,我希望它同时在几个地方,为了克服这个问题,我研究了是否可以确保一个函数一次只能由一个进程使用并暂停其他所有内容, 这打破了异步原则,但我基于例如cpp中的互斥原则。不幸的是,我找不到任何关于它的信息。

节点 .js TypeScript 异步 日志记录 互斥锁

评论

0赞 Dave Newton 7/24/2023
你可能想要诅咒/祝福/等等。
0赞 Devix 7/26/2023
我想到了诅咒,但问题是我正在开发一个 CLI,诅咒肯定是使用菜单等连续运行的程序的替代方案。但是我的代码是为每个命令重新执行的

答: 暂无答案