60

TL;博士

强制保持 Node.js 进程运行的最佳方法是什么,即防止其事件循环运行为空,从而防止进程终止?我能想到的最好的解决方案是:

const SOME_HUGE_INTERVAL = 1 << 30;
setInterval(() => {}, SOME_HUGE_INTERVAL);

如果您保持间隔时间足够长,这将保持间隔运行而不会造成太多干扰。

有更好的方法吗?

问题的长版本

我有一个使用Edge.js注册回调函数的 Node.js 脚本,以便可以从 .NET 中的 DLL 内部调用它。该函数将每秒调用 1 次,发送一个简单的序列号,该序列号应打印到控制台。

Edge.js 部分很好,一切正常。我唯一的问题是我的 Node.js 进程执行了它的脚本,然后它用完了要处理的事件。它的事件循环为空,它只是终止,忽略了它应该一直运行以便能够接收来自 DLL 的回调的事实。

我的 Node.js 脚本:

var
    edge = require('edge');

var foo = edge.func({
    assemblyFile: 'cs.dll',
    typeName: 'cs.MyClass',
    methodName: 'Foo'
});

// The callback function that will be called from C# code:
function callback(sequence) {
    console.info('Sequence:', sequence);
}

// Register for a callback:
foo({ callback: callback }, true);

// My hack to keep the process alive:
setInterval(function() {}, 60000);

我的 C# 代码(DLL):

public class MyClass
{
    Func<object, Task<object>> Callback;

    void Bar()
    {
        int sequence = 1;

        while (true)
        {
            Callback(sequence++);
            Thread.Sleep(1000);
        }
    }

    public async Task<object> Foo(dynamic input)
    {
        // Receives the callback function that will be used:
        Callback = (Func<object, Task<object>>)input.callback;

        // Starts a new thread that will call back periodically:
        (new Thread(Bar)).Start();

        return new object { };
    }
}

我能想出的唯一解决方案是注册一个间隔很长的计时器来调用一个空函数,只是为了让调度程序保持忙碌并避免让事件循环为空,以便进程永远运行。

有没有比我做得更好的方法?即,保持进程运行不必使用这种“黑客”?

4

4 回答 4

46

最简单、侵入性最小的解决方案

老实说,我认为我的方法是侵入性最小的方法:

setInterval(() => {}, 1 << 30);

这将设置一个无害的间隔,大约每 12 天触发一次,实际上什么都不做,但保持进程运行。

最初,我的解决方案用作Number.POSITIVE_INFINITY句点,因此计时器实际上永远不会触发,但这种行为最近被 API 更改,现在它不接受大于 2147483647(即2 ** 31 - 1)的任何值。请参阅此处此处的文档。


对其他解决方案的评论

作为参考,这是迄今为止给出的其他两个答案:

乔的(从那时起已删除,但完全有效):

require('net').createServer().listen();

正如他所说,将创建一个“虚假侦听器”。一个小缺点是我们会为此分配一个端口。

雅各布:

process.stdin.resume();

或等价物:

process.stdin.on("data", () => {});

进入stdin“旧”模式,Node.js 中仍然存在已弃用的功能,以与在 Node.js v0.10 之前编写的脚本兼容(参考)。

我建议不要这样做。它不仅已被弃用,而且还不必要地与标准输入混淆。

于 2017-11-23T13:33:47.420 回答
36

使用“旧”流模式来侦听永远不会出现的标准输入:

// Start reading from stdin so we don't exit.
process.stdin.resume();
于 2014-05-13T03:59:43.440 回答
0

您可以使用setTimeout(function() {""},1000000000000000000);命令使脚本保持活动状态而不会超载。

于 2021-03-14T22:09:57.040 回答
-2

我会再添加一个技巧。以下是如何做到这一点Promise

new Promise(_ => null);

把它放在.js文件的底部,它应该永远运行。

于 2019-03-25T18:21:36.473 回答