Implementing Event Emitters and Listeners

In the following chapters, you have opportunities to implement a lot of the events that are built into the various Node.js modules. This section focuses on creating your own custom events as well as implementing listener callbacks that are implemented when an event is emitted.

Adding Custom Events to Your JavaScript Objects

Events are emitted using an EventEmitter object. This object is included in the events module. The emit(eventName, [args]) function triggers the eventName event and includes any arguments provided. The following code snippet shows how to implement a simple event emitter:

var events = require('events'),
var emitter = new events.EventEmitter();
emitter.emit("simpleEvent");

Occasionally, you will want to add events directly to your JavaScript objects. To do that, you need to inherit the EventEmitter functionality in your object by calling events.EventEmitter.call(this) in your object instantiation. You also need to add events.EventEmitter.prototype to your object prototyping. For example:

Function MyObj(){
  Events.EventEmitter.call(this);
}
MyObj.prototype.__proto__ = events.EventEmitter.prototype;

You can then emit events directly from instances of your object. For example:

var myObj = new MyObj();
myObj.emit("someEvent");

Adding Event Listeners to Objects

Once you have an instance of an object that will emit events, you can add listeners for the events that you care about. You add listeners to an EventEmitter object by using one of the following functions:

Image .addListener(eventName, callback): Attaches the callback function to the object’s listeners. Every time the eventName event is triggered, the callback function is placed in the event queue to be executed.

Image .on(eventName, callback): Same as .addListener().

Image .once(eventName, callback): Only the first time the eventName event is triggered, the callback function is placed in the event queue to be executed.

For example, to add a listener to an instance of the MyObject EventEmitter class defined in the previous section, you would use:

function myCallback(){
  . . .
}
var myObject = new MyObj();
myObject.on("someEvent", myCallback);

Removing Listeners from Objects

Listeners are very useful and a vital part of Node.js programming. However, they cause overhead, and you should use them only when necessary. Node.js provides several helper functions on the EventEmitter object that allow you to manage the listeners that are included:

Image .listeners(eventName): Returns an array of listener functions attached to the eventName event.

Image .setMaxListeners(n): Triggers a warning if more than n listeners are added to an EventEmitter object. The default is 10.

Image .removeListener(eventName, callback): Removes the callback function from the eventName event of the EventEmitter object.

Implementing Event Listeners and Event Emitters

The code in Listing 4.4 demonstrates the process of implementing listeners and custom event emitters in Node.js. The Account object is extended to inherit from the EventEmitter class and provides two methods—deposit and withdraw—that both emit the balanceChanged event. Then in lines 15–31, three callback functions are implemented that are attached to the Account object instance balanceChanged event and display various forms of data.

Notice that the checkGoal(acc, goal) callback is implemented a bit differently than the others. This illustrates how you can pass variables into an event listener function when the event is triggered. Figure 4.7 shows the results of executing the code in Listing 4.4.

Listing 4.4 emitter_listener.js: Creating a custom EventEmitter object and implementing three listeners that are triggered when the balanceChanged event is triggered


01 var events = require('events'),
02 function Account() {
03   this.balance = 0;
04   events.EventEmitter.call(this);
05   this.deposit = function(amount){
06     this.balance += amount;
07     this.emit('balanceChanged'),
08   };
09   this.withdraw = function(amount){
10     this.balance -= amount;
11     this.emit('balanceChanged'),
12   };
13 }
14 Account.prototype.__proto__ = events.EventEmitter.prototype;
15 function displayBalance(){
16   console.log("Account balance: $%d", this.balance);
17 }
18 function checkOverdraw(){
19   if (this.balance < 0){
20     console.log("Account overdrawn!!!");
21   }
22 }
23 function checkGoal(acc, goal){
24   if (acc.balance > goal){
25     console.log("Goal Achieved!!!");
26   }
27 }
28 var account = new Account();
29 account.on("balanceChanged", displayBalance);
30 account.on("balanceChanged", checkOverdraw);
31 account.on("balanceChanged", function(){
32   checkGoal(this, 1000);
33 });
34 account.deposit(220);
35 account.deposit(320);
36 account.deposit(600);
37 account.withdraw(1200);


Image

Figure 4.7 Output of emitter_listener.js, showing the account statements output by the listener callback functions.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.146.178.165