Node.js集群;仅在使用颜色时控制台输出困惑

标签 node.js terminal ansi-escape conemu terminal-color

你好!我正在运行一个包含多个 Node 的集群 Node 项目。他们做了相当多的控制台输出。我也希望能够进行漂亮的彩色输出。

我的问题:我变得困惑,只有在使用颜色时才会出现竞争条件-y 控制台输出。

我一直在将事情归结为隔离我的问题,我当前的设置是让集群中的每个 Node 都有自己唯一的字符串。这是 Node 将输出到控制台的唯一字符串。

let chars = 'abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ';
let getMyUniqueString = () => {
  return chars[Math.floor(Math.random() * chars.length)].repeat(100);
};

我运行了一堆 Node ,它们使用这个函数来确定它们的唯一字符串,我看到了如下内容:

Console output without any jumbling

是不是很漂亮!无论所有这些 Node 输出多长时间和多激烈,这个控制台输出永远不会困惑。

现在,我尝试使用仅包含一点点颜色的独特字符串:

let chars = 'abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ';
let getMyUniqueString = () => {
  let redEscSeq = '\x1b[41m';
  let clearEscSeq = '\x1b[0m';
  let aRedBoxOfText = redEscSeq + '  ' + clearEscSeq;
  let repeatedChars = chars[Math.floor(Math.random() * chars.length)].repeat(100);
  return aRedBoxOfText + repeatedChars;
};

看看我的一些结果看起来多么悲伤!

enter image description here

跨所有 Node 将数据发送到终端的唯一方式是通过 console.log 函数。

为什么 console.log 足够聪明,可以在没有颜色的情况下保持许多 Node 的输出不困惑,但在包含一点颜色的情况下却不够聪明来做到这一点??

感谢您的帮助!

(仅供引用,下图是我希望在彩色情况下始终看到的那种整洁的输出;它只是每行前面的红色框(两个带有红色背景色的空格):)

enter image description here

编辑:虽然此问题存在于 native Windows“cmd.exe”控制台、powershell 控制台和 ConEmu(屏幕截图中显示的一个不错的第 3 方 Windows 终端)中,但它不存在于 Cygwin 终端中!在 Cygwin 中从来没有任何困惑,即使有大量的颜色和异步输出。我可以做些什么来鼓励其他控制台中的这种 Cygwin 行为??

最佳答案

这是一个竞争条件,你不太可能对此做任何事情,也许除了向 nodejs 使用的库报告错误。

虽然 Windows API 本身确实支持在单个 API 调用中打印多色字符串,如下所示:https://learn.microsoft.com/en-us/windows/console/writeconsoleoutput ,其中每个字符都包含其颜色信息。但它也不支持 ANSI 转义码。这不是 javascript 实际使用的内容。

Nodejs 引擎使用一个名为 libuv 的库将字符串写入终端,这是跨平台的,并在内部转换 ANSI 转义码以做正确的事情。但是如果你仔细观察 source of libuv对于处理 ANSI 转义码,您会看到它在每个转义码之后执行完整的缓冲区刷新,这意味着在某些时候它必须变成多个 Windows API 调用才能打印一行文本。

在正常情况下,这显然不是问题,但如果您有多个线程进行写入,则意味着这些行的某些部分可能会变得困惑……就像您在这里看到的那样。

所以这里的答案是无解。或者您接受使用 cygwin 作为解决方案。

关于Node.js集群;仅在使用颜色时控制台输出困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52634075/

相关文章:

shell - 将 ANSI 彩色代码文本发送到 3 个输出 : screen, 文件和文件过滤 ANSI 代码

ruby - 在 Ruby 中执行进程时如何保留输出颜色?

javascript - Svelte:未捕获的 ReferenceError:未定义导出

macos - "ps aux"有效,但 "ps -aux"无效

python - Homebrew 安装后无法运行 Python 3

ubuntu - 用于 shell 的 crontab 不工作

javascript - package.json 的 main、module、browser 属性应该指向 minified 还是 source?

node.js - 是否可以一起使用 winston 日志记录和调试模块?

Javascript:使用 setTimeout 重试的函数

java - 如何在 Java 中转换 linux 伪终端输出?