2012-11-19 64 views
50

根據Understanding the node.js event loop,node.js支持單線程模型。這意味着如果我向一個node.js服務器發出多個請求,它不會爲每個請求產生一個新線程,但會逐個執行每個請求。這意味着如果我爲node.js代碼中的第一個請求執行以下操作,同時在節點上發出新的請求,則第二個請求必須等到第一個請求完成時(包括5秒的休眠時間)。對?如何在不影響其他線程的情況下睡眠node.js中的線程?

var sleep = require('sleep'); 
    sleep.sleep(5)//sleep for 5 seconds 

有沒有一種方式,可以的Node.js生成一個新的線程爲每個請求,使得第二請求,不必等待完成的第一個請求,或可致電我睡在只有特定線程?

+3

你不需要像那樣睡覺。您應該查看setTimeout,而不是 - > http://nodejs.org/api/globals.html#globals_settimeout_cb_ms – Alfred

回答

92

如果您指的是npm模塊sleep,它在自述文件中指出sleep將阻止執行。所以你是對的 - 這不是你想要的。相反,您需要使用非阻塞的setTimeout。這裏有一個例子:

setTimeout(function() { 
    console.log('hello world!'); 
}, 5000); 

對於任何人都希望做到這一點使用ES7異步/ AWAIT,這個例子應該有所幫助:

const snooze = ms => new Promise(resolve => setTimeout(resolve, ms)); 

const example = async() => { 
    console.log('About to snooze without halting the event loop...'); 
    await snooze(1000); 
    console.log('done!'); 
}; 

example(); 
+0

,因此node.js將一次執行一個請求,這意味着它遵循單線程模型。對? – emilly

+6

是的,它使用單個執行線程,因此它一次只能計算一個請求,但可能會有很多請求處於等待狀態。當你調用setTimeout時,它將事件存儲在隊列中,然後可以開始執行下一個請求。五秒鐘後,事件將從隊列中移除並執行回調(在這種情況下,該函數包含'console.log')。 –

+0

查看[此屏幕截圖](http://nodecasts.net/episodes/1-introduction-to-nodejs)瞭解更多關於Node.js如何運行多個請求而不使它們彼此「等待」的更多細節。 –

0

如果你有在一個異步請求環每一個,你想要一定的時間之間每個請求之間,你可以使用此代碼:

var startTimeout = function(timeout, i){ 
     setTimeout(function() { 
      myAsyncFunc(i).then(function(data){ 
       console.log(data); 
      }) 
     }, timeout); 
    } 

    var myFunc = function(){ 
     timeout = 0; 
     i = 0; 
     while(i < 10){ 
      // By calling a function, the i-value is going to be 1.. 10 and not always 10 
      startTimeout(timeout, i); 
      // Increase timeout by 1 sec after each call 
      timeout += 1000; 
      i++; 
     } 
    } 

這個例子等待1秒後,每次在發送下一個之前的任務。

+0

-1。這是**不**會做你的期望。循環不會異步運行。它會立即啓動所有請求。思考與異步循環時要非常小心 - 這種組合很棘手。 – treecoder

+0

當然,這個循環被一次全部調用。但是這個時間會增加每個循環。所以1秒... 2秒... 3秒。這就是爲什麼「myAsyncFunc」會每秒被調用一次,而不是一次調用。當我測試它時,它會按預期工作。你能告訴我你認爲是錯的嗎? – Jodo

+0

順便說一下,代碼確實有點棘手。 _startTimeout_函數立即被調用10次,但每次調用都有一個更大的超時時間,所以每次調用_myAsyncFunc_後會調用一秒。 – greuze