2017-01-25 91 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'}); 
    } 
}