[英]Why does this console log twice?
我想使用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
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())
后者顯然是個問題。 聽眾雖然被命名為名稱並且被上述內容所抹殺,但並不存在。 我不知道為什么?!? 救命!
對於那些有興趣看到整件事的人來說,也有一個回購: 你可以在這里找到它 。
您正在從proc
而不是stdout
刪除偵聽器。 出現雙打是因為您將偵聽器的第二個副本附加到proc.stdout
上的“data”事件中。
添加.stdout
在rmAllListeners
修復它為我:
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')
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.