Javascript NodeJS:在回调函数中追加文件 我有一个电子JS应用程序,启动一个独立的子进程,非阻塞二进制应用程序,我用C++编写。 < >我想将C++标准输出[STDUT]流到NodeJS并将其记录在日志文本文件中。

Javascript NodeJS:在回调函数中追加文件 我有一个电子JS应用程序,启动一个独立的子进程,非阻塞二进制应用程序,我用C++编写。 < >我想将C++标准输出[STDUT]流到NodeJS并将其记录在日志文本文件中。,javascript,node.js,asynchronous,electron,fs,Javascript,Node.js,Asynchronous,Electron,Fs,我已经在NodeJS子流程文档中看到了使用spawn、fork、exec和execFile之间的区别。在我的例子中,我需要使用spawn方法 下面是我的Electron JS/NodeJS代码: const path = require('path'); const fs = require("fs"); const cp = require("child_process"); [... another stuffs ...] // Start a child process: const

我已经在NodeJS子流程文档中看到了使用spawn、fork、exec和execFile之间的区别。在我的例子中,我需要使用spawn方法

下面是我的Electron JS/NodeJS代码:

const path = require('path');
const fs = require("fs");
const cp = require("child_process");

[... another stuffs ...]

// Start a child process:
const child = cp.spawn(my_binary, ["param1", "param2", "param3"], { detached: true });
child.unref();

// STDOUT listener:
child.stdout.setEncoding('utf8');
child.stdout.on("data", (data) => {

    // Set the log file path:
    let filePath = path.join(__dirname, "..", "logs", logFilename);

    // Try to append: I GOT A REFRESH PAGE LOOP HERE:
    fs.appendFile(filePath, data, (err) => {
        if (err) {
            console.error("[STDOUT]", err);
        } else {
            // Get the C++ STDOUT output data:
            console.log(data);
        }
    });
})

此代码实际工作,并在LogiTimeStAM.txt文件中记录C++输出。

我的问题 当我调用这个NodeJS文件时,ElectronJS web界面和浏览器控制台在无限刷新循环中每秒刷新很多次。因此,每当Electron JS刷新页面时,NodeJS都会再次启动一个新的子进程。 最后,我在几秒钟内得到了很多log_timestamp.txt

如果我只删除fs.appendFile并用console.logdata替换它,我只获得了一次所需的控制台日志输出,没有页面刷新或异常行为。 例如:

我做错了什么? 如何在正确的文本文件中正确记录C++输出的方式修复第一个源代码? 我的系统是:

电子7.1.2 节点12.13.0 Windows 10 x64和Ubuntu 18 x64 更新1 按照@Jonas的建议,我尝试了这个替代代码,但我还是得到了同样的异常行为

// Start a child process:
const child = cp.spawn(bin, ["param1", "param2", "param3"], { detached: true });
child.unref();

// STDOUT listener:
child.stdout.setEncoding('utf8');
child.stdout.on("data", (data) => {
    console.log(data);
})

let filePath = path.join(__dirname, "..", "logs", logFilename);
child.stdout.pipe(fs.createWriteStream(filePath));

流的要点是,您可以将它们通过管道连接在一起,让引擎处理所有其他的事务:

 child.stdout.pipe(fs.createWriteStream(/*...*/));

我假设您的主要问题是appendFile必须打开文件、锁定文件、写入文件、解锁文件,这在每个数据块上都会发生。这会减慢写作速度,而且由于您没有正确处理背压,内存消耗开始增加,可能会导致您看到的延迟。

谢谢@Jonas Wilms的快速回答。我做了这个改变,但我也有同样的反常行为。你有其他想法吗?我是ElectronJS和NodeJS编程的新手…所以我不知道如何查找/使用分析器?不正常的事情是:当我尝试将C++输出附加到文本文件时,EnjJs每秒刷新很多次。所以,每次它运行时,NodeJS都会启动一个新的子进程,我得到很多日志文件。我想创建一个日志文件。要做到这一点,我的Electron web界面不能一直刷新。你还有别的建议吗?
 child.stdout.pipe(fs.createWriteStream(/*...*/));