在 node.js 中,我发送到标准输入的数据只有在我调用 end() 后才会到达进程。如果我想继续写作怎么办?

In node.js, data I'm sending to stdin only reaches the process once I call end(). What to do if I want to keep writing?

如果我这样做:

child = child_process.spawn('./resources/backend-exe', {stdio: ['pipe', 'pipe', 'ignore']});
child.stdin.write("Test\n");

子进程没有反应,就好像没有向它发送任何东西一样。但是,如果我这样做(添加一行):

child = child_process.spawn('./resources/backend-exe', {stdio: ['pipe', 'pipe', 'ignore']});
child.stdin.write("Test\n");
child.stdin.end();

它像往常一样对数据做出反应,并向标准输出发送响应。但是,这意味着我无法再写入流。如果我想写几次怎么办?如何在不关闭流的情况下"flush"数据?

子进程的完整代码(Haskell)如下:

module Main where

main :: IO ()
main = do
  line <- getLine
  putStrLn line
  main

当您调用 .write() 时,数据会在一段时间后自动刷新。
(如果您想知道何时刷新,您可以向 .write() 提供回调或监听 drain 事件)

例如:

child.stdin.write("Test\n", () => console.log("FLUSHED!"));

这是两个进程之间的乒乓球的工作示例:repl.it console

如果要处理子进程的输出,将 pipe 传递给 stdio 并在 stdout 上侦听 data

const child_process = require('child_process');

child = child_process.spawn('./program', {stdio: ['pipe', 'pipe', 'ignore']});

// listen for messages from our child
child.stdout.on('data', chunk => {
  console.log("Child sent line: " + chunk.toString());
});

// send a message to the child
child.stdin.write("Test\n");

(完整示例请参见 repl.it console

编辑: 您的问题似乎与缓冲有关。 Haskell 将检查您的程序是否在 tty 上下文中 运行,即程序是否直接连接到控制台,并相应地设置缓冲策略。

如果您从控制台启动 haskell 程序,haskell 将使用 LineBuffering。
但是,如果您在非 tty 上下文中调用它,它将使用块缓冲。 您可以通过调用

重置缓冲策略
hSetBuffering stdin LineBuffering
hSetBuffering stdout LineBuffering

使用 LineBufferingNoBuffering 让 haskell 进程再次响应每一行。