event模塊是nodejs系統中十分重要的一個模塊,使用該模塊我們可以實現事件的綁定的觸發,為什么我們需要這個模塊呢,因為nodejs是單線程異步的。
一、什么是單線程異步:
我們可以從JavaScript來理解,就是存在一個等待執行隊列,每當有代碼行為產生,我們便將其隨機放到等待執行隊列,但是由於單線程的原因,我們一次只能處理一個任務,只有在當線程空閑時才能處理下一個任務,在線程處理時,我們仍然可以將要處理的任務放到等待執行隊列中,也就說線程的任務處理和我們讀取代碼放任務到等待執行隊列上這兩個行為是可以同時進行的,即異步,線程一次只能處理一個任務,即單線程。
如下例子:
setTimeout(function (){ console.log('I am coming'); }, 100); console.log('before while');
結果是先打印before while,然后再打印I am coming,而不是在100ms的延時時阻塞之后代碼的執行,注冊定時器后繼續執行之后的代碼。
二、event模塊的主要方法:
- on:添加事件(事件隊列尾部添加)
- once:添加只能觸發一次便失效的事件(事件隊列尾部添加)
- prependListener:添加事件(添加到事件隊列頭部)
- prependOnceListener:添加只能觸發一次便失效的事件(添加到事件隊列頭部)
- emit:觸發事件
- removeListener:刪除某個事件
- on(eventName, listener[, arg1][, arg2]...)
eventName:注冊事件名字
listener:事件處理函數
arg1,arg2:往事件處理函數中傳入的參數
"use srict"; const Event = require('events'); const event1 = new Event(); event1.on('come', function () { console.log('I am coming'); }); event1.emit('come'); // I am coming
2. once 同on,但是只能觸發一次,觸發一次后便從事件隊列中刪除
3. prependListener 同on,但是是往事件隊列頭部添加
4. prependOnceListener 同on,但是是往事件隊列頭部添加,且只能觸發一次
5. emit(eventName)觸發eventName事件
6. removeListener(eventName)解除eventName事件綁定
同一事件可以綁定多次,觸發時按照事件隊列順序執行,on和once是往事件隊列尾部添加,prependListener和prependOnceListener是往事件隊列頭部添加,這便形成了同一事件的執行順序
"use srict"; const Event = require('events'); const event1 = new Event(); event1.on('come', function () { console.log('I am coming01'); }); event1.on('come', function () { console.log('I am coming02'); }); event1.prependListener('come', function () { console.log('I am coming03'); }) event1.emit('come'); /* I am coming03 I am coming01 I am coming02 */
event方法簡單模擬實現:
"use strict"; // evnet 實現模擬 EventEmitter.prototype = { // on方法 on: function(eventName, cb) { this.events[eventName] = cb; }, // emit,傳參 emit: function(eventName) { const args = Array.prototype.slice.call(arguments, 1); const cb = this.events[eventName]; cb.apply(this, args); console.log(this); }, } function EventEmitter() { this.events = {}; } const event1 = new EventEmitter(); event1.on('call', (name, word) => { console.log('I am calling,', name, word); }); event1.emit('call', 'john', 'hello'); // I am calling
三、event模塊的繼承:
event模塊可以被其他類繼承,從而具有event模塊的屬性
兩種方法:
1、util.inherits
"use srict"; const Event = require('events'); const util = require('util'); // Phone類 Phone.prototype.message = function () { console.log('I am sending message'); } function Phone() {} // 通過util.inherits繼承 util.inherits(Phone, Event); // 測試 const phone = new Phone(); phone.on('call', function () { this.message(); }); phone.emit('call'); // I am sending message
2、通過ES6的extends實現繼承(推薦)
"use srict"; const Event = require('events'); // extends class Phone extends Event { message() { console.log('I am sending message'); } } // 測試 const phone = new Phone(); phone.on('call', function () { this.message(); }); phone.emit('call'); // I am sending message
----------------------------------------------------------------------------------end