簡體   English   中英

為什么這個控制台會記錄兩次?

[英]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”事件中。

添加.stdoutrmAllListeners修復它為我:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM