接觸Node,提得最多的可能就是回調,異步非阻塞處理,思前想後,JavaScript從前端語言過渡到服務器端,最大的劣勢可能就是線程,固然這方面的不足如今也被慢慢彌補起來了(不少第三方的npm包可供下載),而在初期時,其語言的執行思想也是偏向多線程的,因而用了一個很是巧妙的方法:事件驅動。javascript
Node.Js使用事件驅動模型,當web server接收到請求,就把它關閉而後進行處理,而後去服務下一個web請求。當這個請求完成,它被放回處理隊列,當到達隊列開頭,這個結果被返回給用戶。這個模型很是高效可擴展性很是強,由於webserver一直接受請求而不等待任何讀寫操做。(這也被稱之爲非阻塞式IO或者事件驅動IO)前端
這邊引用以前看過的一篇博客上的圖及setTimeout的說明java
這邊就要借用setTimeout()函數來講明Node的事件驅動機制,首先運行下面一段函數node
console.log("aaaa"); for(i=1;i<3;i++){ setTimeout(function(){console.log(i)},0) } console.log("bbbb");
運行結果:web
比較怪異的是console完aaaa以後並無當即console setTimeout裏的函數,固然若是這裏去掉setTimeout改成console結果仍是會如咱們想象的同樣,固然咱們要講的是事件驅動,因此這邊用一個setTimeout(fuc,0)來表示當即執行。而咱們看到了setTimeout執行落在了正常事件的最後,以前看的一篇博客,博主寫的是setTimeout函數若是置零,也不會當即執行,由於HTML5默認規範對於setTimeout函數有2ms的延遲,那會不會是由於這2ms的延遲導致輸出延時了呢,因而咱們改進下代碼consolenpm
console.log("aaaa"); for(i=1;i<3;i++){ setTimeout(function(){console.log(i)},500);console.log("bbbb"); } for(n=1;n<4;n++){ console.error(n); } console.log("cccc");
運行結果:瀏覽器
設置了500ms延遲,以後也用了for循環作了3s的阻塞,可是輸出結果仍是延時,因此setTimeout執行的延時並不是咱們想象的那樣,而結合nodeJs的事件代理,咱們得知當js運行到setTimeout時,實際上爲了避免形成阻塞,會將setTimeout時間扔到瀏覽器的時間隊列中,當函數從頭至尾執行完後,再拋出咱們setTimeout的輸出結果服務器