2013-07-24 104 views
0

的其餘部分的執行我有一個的NodeJS代碼片段是這樣的:在每2秒,FOO平行執行的功能,同時完成代碼

()將被調用。

function foo() 
{ 
    while (count < 10) 
    { 
     doSometing() 
     count ++;`` 
    } 
} 

doSomething() 
{ 
    ... 
} 

限制是,foo()沒有回調。 如何使while循環執行和foo()完成而無需等待dosomething()完成(調用dosomething()並繼續)和dosomething()並行執行?

回答

0

我認爲,你想要的是:

function foo() 
{ 
    while (count < 10) 
    { 
     process.nextTick(doSometing); 
     count ++; 
    } 
} 

process.nextTick將安排在事件循環的下一個節拍的doSometing執行。因此,不是立即切換到doSometing,這段代碼只會安排執行並首先完成foo

您也可以嘗試setTimeout(doSometing,0)setImmediate(doSometing)。他們將允許I/O調用發生在doSometing將被執行之前。

將參數傳遞給doSomething

如果你想傳遞一些參數來doSomething,那麼最好以確保它們會被封裝,不會改變doSomething將被執行前:

setTimeout(doSometing.bind(null,foo,bar),0); 

在這種情況下,即使foobar將被更改或刪除,也會使用正確的參數調用doSometing。但是,如果foo是一個對象,並且您更改了其中一個屬性,則這不起作用。

替代方案是什麼?

如果你想doSomething並行執行(不只是異步,但實際上並行),那麼你可能會對某些作業處理解決方案感興趣。我建議你看看kickq

var kickq = require('kickq'); 

kickq.process('some_job', function (jobItem, data, cb) { 
    doSomething(data); 
    cb(); 
}); 

// ... 

function foo() 
{ 
    while (count < 10) 
    { 
     kickq.create('some_job', data); 
     count ++; 
    } 
} 

kickq.process將爲您處理工作的獨立進程。因此,kickq.create將只註冊要處理的作業。

kickq使用redis排隊作業,沒有它就無法工作。

如何使用Node.js內置的模塊

另一種方法是使用Child Process構建自己的工作處理器。生成的代碼可能是這個樣子:

var fork = require('child_process').fork, 
    child = fork(__dirname + '/do-something.js'); 

// ... 

function foo() 
{ 
    while (count < 10) 
    { 
     child.send(data); 
     count ++; 
    } 
} 

do-something.js這裏是一個單獨的文件.jsdoSomething邏輯:

process.on('message', doSomething); 

實際的代碼可能會更復雜。

事情你應該知道的

Node.js是單線程的,因此它一次只能執行一個功能。它也不能利用多於一個CPU。

Node.js是異步的,所以它能夠通過在它們之間切換來同時處理多個函數。處理具有大量I/O調用的函數時非常高效,因爲它是較新的塊。因此,當一個函數等待來自DB的響應時,將執行另一個函數。但是node.js不適合阻止CPU使用率過高的任務。

使用child_processcluster等模塊可以在node.js中進行真正的並行計算。 child_process允許您啓動新的node.js過程。它還創建父級和子級進程之間的通信通道。集羣允許您運行一組相同的進程。當您處理http請求時,它非常方便,因爲cluster可以在工作人員之間隨機分配它們。因此,可以創建一組並行處理數據的工作人員,但通常node.js是單線程的。

+0

@Lenoid我知道process.nextTick()將工作。但nextTick()在任何I/O之前執行排隊的事件。看到這裏:http://stackoverflow.com/questions/16220710/understanding-the-node-js-event-queue-and-process-nexttick。這裏foo()是一個I/O調用,我想doSomething()在後臺執行,然後foo()開始執行。但nextTick()會在啓動下一個foo()之前使所有排隊的doSomething()被執行。 – nebi

+0

然後使用'setTimeout'。它不會阻止'I/O'操作。 –

+0

@ Leonid大概可以幫到 – nebi