异步回调阻止NodeJS

时间:2017-01-06 19:27:09

标签: node.js

我有一个基于服务器客户端的NODE.JS应用程序。

server.js

...
socket.on('message', function(message) {
    if(message.code == 103)
    {
        process_some_data()
    }
    else
    {
        console.log("UNKNOWN MESSAGE");
    }
});
...

client.js

.. sending responses back to server.js

process_some_data()函数需要大约4秒才能完成,当我只有一个客户端时,这不是问题,但如果我有10个,它们都会窒息并等到最后一个完成。

我发现整个socket事件等到他完成当前的工作,例如,如果我评论process_some_data(),它将不会被冻结

我尝试了2次调整但是没有用过:

...
socket.on('message', function(message) {
    if(message.code == 103)
    {
        setTimeout(function() {
            process_some_data();

            console.log("FINISH");
        }, 1)
    }
    else
    {
        console.log("UNKNOWN MESSAGE");
    }
});
...

甚至使用http://caolan.github.io/async/,但没有用:

...
socket.on('message', function(message) {
    if(message.code == 103)
    {
        // Array to hold async tasks
        var asyncTasks = [];

        async.series([
            setTimeout(function() {

                process_some_data();

                console.log("FINISH");
            }, 1)
        ], function (err, results) {
            console.log(results);
        });
    }
    else
    {
        console.log("UNKNOWN MESSAGE");
    }
});
...

如何制作ASYNC?真的需要这个。

谢谢。

1 个答案:

答案 0 :(得分:1)

您需要多个流程才能使用Javascript解决此问题,因为Javascript引擎单线程

什么?

当涉及到处理I / O事件时,例如读取套接字,写入文件或等待信号,Javascript引擎可以同时执行多项操作。

它们实际上不是:它只是说,在大多数情况下,处理这些事件所需的计算量很少,并且事件本身会在两者之间发生很长时间(一微秒是对于CPU来说是永恒的,引擎可以一个接一个地处理它们,并且有足够的时间来备用。

在人类时间尺度上,看起来就像引擎并行执行大量工作一样,但它只是以极快的速度连续工作。

无论您如何使用setTimeoutPromise计划运行代码,它仍会阻止其他事件在其主动计算期间进行处理。长时间运行的计算(以秒为单位,而不是毫秒)暴露了引擎的单线程特性:它实际上不能同时执行多个操作。

多个流程

但是,您的计算机可能有多个CPU核心。与Javascript引擎不同,您的硬件能够同时处理多个任务,每个核心至少1个。即使使用单核,如果运行多个进程,操作系统也可以解决问题。

由于单个Javascript进程是单线程的,因此您需要多个Javascript进程。一个简单且久经考验的架构可以解决您的问题:

  • 在一个进程中运行的一个Javascript程序从socket读取。但是,它不是调用process_some_data(),而是将所有传入的消息放入队列中。

  • 然后,该程序将项目从队列发送到另一个Javascript程序,该程序在不同的进程中运行,该程序使用另一个CPU核心执行计算。第二个过程可能有多个副本。在现代计算机中,拥有两倍于CPU内核的活动进程是有意义的。

Node的一个简单方法是使用express编写一个运行计算密集型任务的HTTP服务器。然后,主程序可以使用HTTP将任务委派给worker,同时仍然可以从套接字读取。

This是一篇关于使用cluster API进行多处理的主题的好文章。

相关问题