交叉從Reddit發佈。
JavaScript中異步函數的用途與您尋求的有點不同。
請記住,JavaScript是單線程的 - 它一次只能做一件事。下面是一些傳統的,阻塞代碼:
sys.puts("Before");
sleep(10);
sys.puts("After");
在真實世界中的Web應用程序中,sleep()
可能反而是一個耗時的數據庫調用,網絡請求(如從用戶的Web瀏覽器等待數據),幫手工具或文件訪問。
如果您使用類似上述的阻塞調用,則Node.js服務器在等待時無法執行其他任何操作(如開始處理其他Web請求)。
PHP和許多其他Web編程環境通過爲每個請求創建完全獨立的線程來處理此問題。 Node.js使用回調函數。你可以寫相同的代碼是這樣,而是:
sys.puts("Before");
setTimeout(function(){
sys.puts("After");
}, 10000);
在這裏,你創建一個函數,並把它傳遞給setTimeout()
。它的代碼還沒有運行,但是當它運行時,它將訪問它創建的所有範圍(所有變量)。 setTimeout()
獲取對該功能的引用,並在超時到期後安排要在the event loop上觸發的事件。
事件循環本質上是一個Node.js程序的待辦事項列表(它們很常見 - 您的計算機上運行的所有GUI應用程序都可能使用事件循環!)。
呼叫setTimeout()
後,當前函數繼續執行。它最終返回,並調用它的函數返回,等等,直到程序結束回事件循環。事件循環查看代碼執行時是否發生任何事情(例如傳入請求),並在代碼中調用相應的函數。如果沒有,則等待發生(如超時到期)。
異步代碼不讓你的代碼在同一時間做很多事情,它並消除當一些代碼依賴於外在的東西繼續阻止。
很少有您需要在Node.js程序中阻止工作。如果你這樣做了,你應該把這個工作分解成一個單獨的進程(甚至可以是另一個Node.js程序),或者編寫可以自由使用線程的a C/C++ addon。
來源
2011-08-01 19:30:13
s4y
你知道我在node.js中如何實現這個功能嗎?謝謝 – Richard 2010-05-20 21:37:58
這個問題很老舊,但對於像我這樣的node.js初學者來說,仍然非常有趣。如前所述,node.js是針對並行I/O而非並行工作的。這意味着:如果你有一個耗時的工作來響應單個請求node.js不會加快你在單個請求中嘗試實現的內容。 使用sleep()和setTimeout()之間的區別在於,當使用sleep()進行睡眠時,node.js將阻止所有其他請求 - 使用setTimeout()將不會阻止其他請求。或者:10個睡眠請求(10s)將需要100s - 10個請求setTimeout(10s)只需10s。 – schlicki 2016-03-04 19:49:54