你好!我正在运行一个包含多个 Node 的集群 Node 项目。他们做了相当多的控制台输出。我也希望能够进行漂亮的彩色输出。
我的问题:我变得困惑,只有在使用颜色时才会出现竞争条件-y 控制台输出。
我一直在将事情归结为隔离我的问题,我当前的设置是让集群中的每个 Node 都有自己唯一的字符串。这是 Node 将输出到控制台的唯一字符串。
let chars = 'abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ';
let getMyUniqueString = () => {
return chars[Math.floor(Math.random() * chars.length)].repeat(100);
};
我运行了一堆 Node ,它们使用这个函数来确定它们的唯一字符串,我看到了如下内容:
是不是很漂亮!无论所有这些 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;
};
看看我的一些结果看起来多么悲伤!
跨所有 Node 将数据发送到终端的唯一方式是通过 console.log
函数。
为什么 console.log
足够聪明,可以在没有颜色的情况下保持许多 Node 的输出不困惑,但在包含一点颜色的情况下却不够聪明来做到这一点??
感谢您的帮助!
(仅供引用,下图是我希望在彩色情况下始终看到的那种整洁的输出;它只是每行前面的红色框(两个带有红色背景色的空格):)
编辑:虽然此问题存在于 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/