gpt4 book ai didi

javascript - 为什么这个控制台记录两次?

转载 作者:搜寻专家 更新时间:2023-10-31 22:49:07 26 4
gpt4 key购买 nike

我正在尝试做的事情:

我想使用 Node 在特定时间以特定顺序启动两个子进程,控制台在它们流式传输时记录它们的 stdout,偶尔在两者之间切换。

我想要的输出:

`Proc 1 log # 1`
`Proc 1 log # 2`
`Proc 1 log # 3`
`Proc 1 log # 4`
`Proc 2 log # 1`
`Proc 2 log # 2`
`Proc 2 log # 3`
`Proc 2 log # 4`
`Proc 1 log # 9`
`Proc 1 log # 10`
`Proc 1 log # 11`
`Proc 1 log # 12`
`Proc 1 log # 13`
`Proc 1 log # 14`
`Proc 1 log # 15`
`All procs have finished!`

当然,这非常容易做到。 命令式。但它也真的很丑陋和有状态而且只是呃。所以我试图纯粹地去做,并使用 Task 建立了计算folktale 中的 monad(也就是旧的),像笨蛋一样手动穿过有状态的对象:

//    main _ :: Task error {childProcs}
const main = startProc1({})
.chain(logUntilProc1IsReady)
.chain(startProc2)
.chain(logUntilProc2IsReady)
.chain(logUntilProc1IsFinished)

漂亮多了。如果它有效,它也会好得多!

我得到的输出:

`Proc 1 log # 1`                                       
`Proc 1 log # 2`
`Proc 1 log # 3`
`Proc 1 log # 4`
`Proc 2 log # 1`
`Proc 1 log # 6` // <-- These should not be logged
`Proc 2 log # 2`
`Proc 1 log # 7`
`Proc 2 log # 3`
`Proc 1 log # 8`
`Proc 2 log # 4`
`Proc 1 log # 9`
`Proc 1 log # 10` // <-- now it's logging twice! :confounded:
`Proc 1 log # 10`
`Proc 2 log # 6`
`Proc 1 log # 11`
`Proc 1 log # 11`
`Proc 2 log # 7`
`Proc 1 log # 12`
`Proc 1 log # 12`
`Proc 2 log # 8`
`Proc 1 log # 13`
`Proc 1 log # 13`
`Proc 2 log # 9`
`Proc 1 log # 14`
`Proc 1 log # 14`
`Proc 2 log # 10`
`All procs have finished!`

我做过的事情:

这是日志记录函数:

//    logStreamUntil :: int -> (a -> bool) -> proc -> string -> Task error State () {childProcs}
const logStreamUntil = curry((predFunc, procName, procObj) =>
new Task ((_, res) => {
const proc = procObj[procName]
const logUntilPred = data =>
predFunc(data)
? (rmAllListeners(proc), res(procObj))
: console.log(data)
proc.stdout.on('data', logUntilPred)
}))

其中 tl;dr: 是我向它发送了一个进程名称和要从中提取实际子进程的对象,以及一个用于决定控制台记录多长时间的谓词函数 stdout 被扔给它的任何子进程。谓词只是在 stdout 的字符串中寻找特定的东西。所以它在谓词函数返回 false 时控制台记录输出,否则它停止记录,删除监听器,应该就是这样!

然后是 rmAllListeners 函数:

//    rmAllListeners :: childProc -> childProc           
const rmAllListeners = proc => (proc.removeAllListeners(), proc.stdout.unref())

后者显然是问题所在。听众,尽管被命名空间命名并被上述内容抹杀,但实际上并没有。我不知道为什么?!?帮助!

进一步阅读:

对于那些有兴趣看到整个事情的人来说,还有一个它的 repo :you can find it here .

最佳答案

您正在从 proc 而不是 stdout 中移除监听器。 double 出现是因为您将监听器的第二个副本附加到 proc.stdout 上的“数据”事件。

rmAllListeners 中添加 .stdout 为我修复了它:

diff --git a/why-log-twice.js b/why-log-twice.js
index 276d15c..6c15467 100644
--- a/why-log-twice.js
+++ b/why-log-twice.js
@@ -7,7 +7,7 @@ const PROC_ONE_PATH = `node child-proc "Proc 1 log # "`
const PROC_TWO_PATH = `node child-proc "Proc 2 log # "`

// rmAllListeners :: childProc -> childProc
-const rmAllListeners = proc => (proc.removeAllListeners(), proc.stdout.unref())
+const rmAllListeners = proc => (proc.stdout.removeAllListeners(), proc.stdout.unref())

// procIsReady :: string -> bool
const procIsReady = str => str.includes('5')

关于javascript - 为什么这个控制台记录两次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51992420/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com