Node中的事件循環瀏覽器
事件循環是Node的核心,正是由於有了事件循環JS纔可以在服務端佔有一席之地。JS是一種單線程語言,可是它的執行環境是多線程的在加上JS的事件驅動這一特色,使使JS在執行的過程當中沒執行到一個異步操做就交由後臺處理而後繼續向下執行,在趕上一個異步操做又交由後臺處理,JS的執行線程不會發生阻塞,一旦JS代碼執行完畢就會去後臺查看有沒有知足條件的異步操做一旦有知足條件的就執行事先定義好的處理函數。多線程
在Node中經過EventEmitter(事件發生器)來實現這種功能,EventEmitter和咱們在瀏覽器中使用自定義事件的方式是差很少的,其使用方式爲:異步
var events = require("events").EventEmitter; var event = new events; event.on("zt",function(){console.log(111)}); event.emit("zt");
經過require("events").EventEmitter來獲取事件發生器函數,咱們在實例化一個對象,這樣這個對象就得到了事件發生器原型上的方法,分別爲on和emit,咱們能夠經過on()函數來註冊一個事件,它能夠接收兩個參數第一個參數爲eventName,第二個參數爲對應的事件處理函數。在綁定事件以後能夠經過emit來主動觸發事件。函數
事件發生器能夠爲一個事件綁定多個事件處理函數,而且它的執行順序是能夠保證的,在前面的優先執行:ui
var events = require("events").EventEmitter; var event = new events; event.on("zt",function(){console.log("我是第一個處理函數")}); event.on("zt",function(){console.log("我是第二個處理函數")}); event.emit("zt");
事件處理函數一樣能夠接收參數,在主動觸發時傳入參數便可:spa
var events = require("events").EventEmitter; var event = new events; event.on("zt",function(a,b){console.log("我是第一個處理函數"+"參數1:"+a+"參數2:"+b)}); event.on("zt",function(a){console.log("我是第二個處理函數"+"參數1:"+a)}); event.emit("zt","AA","BB");
在使用emit()時第一個參數表示要觸發的事件,後面的參數就表示事件處理函數的參數。線程
事件發生器能夠實現異步,但其自己是同步的:code
var events = require("events").EventEmitter; var event = new events; event.on("zt",function(){console.log("我是第一個處理函數")}); event.on("zt",function(){console.log("我是第二個處理函數")}); setTimeout(function(){ event.emit("zt"); },1000); event.on("zt",function(){console.log("我是第三個處理函數")});
事件發生器的on方法等價於一個存儲方法,它會把事件名和事件處理函數存儲起來,並不會執行,一旦使用emit觸發事件以後執行已經存儲的處理函數,在emit觸發事件後已經添加的事件處理函數就會當即執行,這個操做並非異步的。對象
var events = require("events").EventEmitter; var event = new events; event.on("zt",function(){console.log("我是第一個處理函數")}); event.on("zt",function(){console.log("我是第二個處理函數")}); event.emit("zt"); event.on("zt",function(){console.log("我是第三個處理函數")});
將上面的定時器去掉,若是emit是一個異步操做那麼第三個處理函數就會執行,可是事實上程序只是執行了前兩個事件處理函數。blog