2017-01-25 61 views
6

我试图使用node-unfluff,它从HTML字符串中提取内容。但是,它通常需要〜200ms才能运行。由于它同步运行,所以速度太慢。我想让它异步运行。Web Worker vs child_process Node.js中CPU密集型功能

据我所知,我的选择是Web Workers(https://github.com/audreyt/node-webworker-threads)或child_process(​​)。还有其他更好的选择吗?

如果不是这样,在速度或其他因素方面哪个更好?

编辑:

还有线程GOGO(https://github.com/xk/node-threads-a-gogo)和微小的工人(https://github.com/avoidwork/tiny-worker)。

WebWorker线程不支持require,所以这不再是一个选项。

通过使用load函数,可以使用Threadsàgogo的require文件,但它看起来像是一个拙劣的解决方法。

小工作者目前在Github上只有26颗星,所以我很犹豫在生产代码中使用它。它支持require

我正在考虑使用child_process编写我自己的WebWorker实现,如果没有更好的选项。

+0

你能解释一下你的使用情况多一点?您是否试图在处理多个URL时获得并行性,或者您是否想要以某种方式提高节点不结盟性能?当您依赖Node中的库时,您是如何设想使用子进程的?为什么标准节点集群不是您列表中的选项(请记住,它确实依赖子进程本身)? – SylonZero

+0

我使用节点作为服务器。如果一个函数需要200ms运行,那么用户不能在200ms内获得服务器响应。我想使它异步,以便服务器不被阻塞。我可以使用'child_process'来启动另一个Node进程。我从来没有使用节点集群,但我的理解是它为每个核心创建一个服务器。如果在每个核心上运行'node-unfluff',则每个服务器都被阻塞。 –

+0

好的,你的问题开始变得更加清晰。但是,即使某个函数的实例(使用节点不分散)是同步的,也不会阻止用于其他节点的其他实例被释放。因此,单个用户可能需要等待200ms,但这通常不意味着对其他用户的请求无法启动。你有没有测试过,发现使用这个unfluff模块实际上阻止了并发请求? – SylonZero

回答

1

您可以使用Require与Worker。在你的工人脚本,你将需要调用

self.importScripts('../path/require.js'); 

按要求的文档,你可以通过一个配置对象模块:

requirejs.config({ 
    //By default load any module IDs from js/lib 
    baseUrl: 'js/lib', 
    //except, if the module ID starts with "app", 
    //load it from the js/app directory. paths 
    //config is relative to the baseUrl, and 
    //never includes a ".js" extension since 
    //the paths config could be for a directory. 
    paths: { 
     app: '../app' 
    } 
}); 

// Start the main app logic. 
requirejs(['jquery', 'canvas', 'app/sub'], 
function ($,  canvas, sub) { 
    //jQuery, canvas and the app/sub module are all 
    //loaded and can be used here now. 
}); 

将其组合在一起

工人。 js

self.importScripts('../path/require.js'); 
requirejs.config({ 
    //By default load any module IDs from path/lib 
    baseUrl: 'path/lib', 
    //except, if the module ID starts with "app", 
    //load it from the js/app directory. paths 
    //config is relative to the baseUrl, and 
    //never includes a ".js" extension since 
    //the paths config could be for a directory. 
    paths: { 
     app: '../app' 
    } 
}); 

// Start the main app logic. 
requirejs(['jquery', 'canvas', 'app/sub'], 
function ($,  canvas, sub) { 
    //jQuery, canvas and the app/sub module are all 
    //loaded and can be used here now. 
    // now you can post a message back to your callee script to let it know require has loaded 
    self.postMessage("initialized"); 
}); 

self.onmessage = function(message) { 
    // do cpu intensive work here, this example is not cpu intensive... 
    if(message.data === 'to process') { 
     self.postMessage("completed!"); 
    } 
} 

节点工人呼叫

var worker = new Worker('Worker.js'); 
worker.onmessage = function(event) { 
    var msg = event.data; 
    if(msg === 'initialized') { 
     worker.postMessage({data: 'to process'}); 
    } 
}