Detailed Node.js:events Event Module _node.js

Source: Internet
Author: User
Tags emit event listener

Most of the core APIs for Nodejs are based on asynchronous event-driven design, and all objects that can distribute events are instances of the Eventemitter class.

As you know, because Nodejs is single-threaded, Nodejs needs event polling to continually query event messages in the event queue, and then execute the callback function for that event, somewhat like the Windows message mapping mechanism. For finer implementation links, you can find information separately.

The following describes the use of Eventemitter.

1. Listening for events and distributing events

Eventemitter instances can use on or addlistener listener events, emit () method distributes events as follows:

Const EVENTS = require (' Events '),
   eventemitter = events. Eventemitter,
   util = require (' util ');
function Myemiter () {
  eventemitter.call (this);
};
Util.inherits (Myemiter,eventemitter)//Inherit Eventemitter class
const Myemitterins = new Myemiter ();
Myemitterins.on (' Data ', (o) =>{
  console.log (' Receive the data: ' +o.a);
};

or use class classes

Class Myemiter extends eventemitter{}//inherits Eventemitter class
const Myemitterins = new Myemiter ();

Myemitterins.on (' Data ', (o) =>{
  console.log (' Receive the data: ' +o.a);
};
Myemitterins.emit (' data ', {a:1});

The results of the implementation are as follows:

E:\developmentdocument\nodejsdemo>node Event-example.js
Receive the Data:1

2, to the event listener callback function pass parameters

As you can see from the example above, a emit() method can pass any set of arguments to a callback function, and note that the This keyword points to a eventemiter instance that calls the emit method, but in the arrow function, this points to global this, Because this in the arrow function is bound at definition time. As shown below:

Class Myemiter extends eventemitter{}
const Myemitterins = new Myemiter ();
Myemitterins.on (' Data ', function (data) {
  Console.log ("This:" in the normal callback function);
  Console.log (this);
};
Myemitterins.on (' Data1 ', (data1) =>{
  console.log ("This:" in the arrow callback function);
  Console.log (this);
};
Myemitterins.emit (' data ', {a:1});
Myemitterins.emit (' Data1 ', {a:1});

The results of the implementation are as follows:

E:\developmentdocument\nodejsdemo>node Event-example.js
This is in the normal callback function:
Myemiter {
Domain:null,
_events: {data: [function], data1: [function]},
_eventscount:2,
_maxlisteners:undefined}
In the arrow callback function, this:
{}

Here's what this is in the arrow function, by the way, why the arrow function binds this when it is defined, because there is no mechanism within the arrow function to bind this, it uses this of the outer scope, and therefore it cannot be a constructor.

3. Sequence of execution of event listeners

Eventemiter instances can bind multiple events, and when we trigger these events sequentially, Eventemiter executes in synchronous mode, and the next event is not triggered when the first event handler is not completed, as follows:

Class Myemiter extends eventemitter{}
const Myemitterins = new Myemiter ();
Myemitterins.on (' Data ', function (data) {
  console.time (' data event executed ');
  for (var i = 0; i< 100000, i++) for
    (var j = 0; j< 100000; j +)
      ;
  Console.timeend (' data event executed ');
};
Myemitterins.on (' Data1 ', (data1) =>{
  console.log ("Data1 event begins execution ...");
Myemitterins.emit (' data ', {a:1});
Myemitterins.emit (' Data1 ', {a:1});

The results of the implementation are as follows:

E:\developmentdocument\nodejsdemo>node Event-example.js
The data event was executed: 4721.401ms
Data1 Event started ...

Of course, we can use asynchronous operations in the callback function, such as settimeout,setimmediate or Process.nexttick (), to achieve the effect of asynchrony, as follows:

Myemitterins.on (' Data ', function (data) {
  setimmediate () =>{
    console.log (the ' data event executes ... ');
  })
;

The results of the implementation are as follows:

E:\developmentdocument\nodejsdemo>node Event-example.js
Data1 Event executed ...
The data event executes ...

4, one-time event monitoring

Eventemiter can use once to listen for an event, the event handler will only fire once, and then emit the event will be ignored because the listener is logged off as follows:

Myemitterins.once (' One ', (data) =>{
  console.log (data);
});
Myemitterins.emit (' One ', ' This is-is-call! ');
Myemitterins.emit (' One ', ' This is second call! ');

The results of the implementation are as follows:

E:\developmentdocument\nodejsdemo>node Event-example.js
This is the call!

As seen from the above results, the ' one ' event was only executed once.

5. Remove Event Bindings

Similar to DOM event sniffing, Eventemiter can also remove event bindings and use removeListener(eventName,listener) methods to unbind an event, so the callback function listener must be a named function, otherwise the function cannot be found because the function is a reference type, even if the function body is the same and not the same function , as follows:

Myemitterins.on (' Data ', function (e) {
  console.log (e);
});
Myemitterins.removelistener (' Data ', function (e) {
  console.log (e);
});
Myemitterins.emit (' Data ', ' Hello data! ');
Function Deal (e) {
  console.log (e);
}
Myemitterins.on (' data1 ', Deal);
Myemitterins.removelistener (' data1 ', Deal);
Myemitterins.emit (' data1 ', ' Hello data1! ');

The results of the implementation are as follows:

E:\developmentdocument\nodejsdemo>node Event-example.js
Hello data!
E:\developmentdocument\nodejsdemo>

As you can see from the execution results, the data event uses an anonymous function, so it is not removed, and the Data1 event is successfully unbound. One thing to note here is that all the callback functions that are bound to the event are invoked after emit triggers an event, even if you use the RemoveListener function to remove another callback in one of the callback functions, but the subsequent event queue removes the callback. As shown below:

function DealData1 (e) {
  console.log (' Data event executed ... A ');
Myemitterins.on (' Data ', function (e) {
  console.log (e);
  Myemitterins.removelistener (' data ', dealData1);//Unbind dealData1 here
});
Myemitterins.on (' data ', dealData1);
Myemitterins.emit (' Data ', ' data event ') executed ... B ');
/* Execution result is:
 The data event executes ... B
 The data event executes ... A
///
When the event is triggered again, the DEALDATA1 callback has been unbound
myemitterins.emit (' Data ', ' data event executed ... ');
The data event executes ...

You can also use removeAllListeners() a binding that unlocks all events.

6. Get the number of event listeners and the listening function

Use the function to get the number of listeners for the emitter.listenerCount(eventName) specified event, which emitter.listeners(eventName) can be used to get all the listener functions for the specified event, using the following:

var CbA = () =>{},
  CbB = () =>{};
var emitter = new Myemiter ();
Emitter.on (' data ', CbA);
Emitter.on (' data ', CbB);
Console.log (the ' Emitter instance's data event binds%d callback functions ', Emitter.listenercount (' data '));
Console.log (' They are: ', emitter.listeners (' data '));

The results of the implementation are as follows:

E:\developmentdocument\nodejsdemo>node Event-example.js
The emitter instance's data event binds 2 callback functions
They are: [[FUNCTION:CBA], [FUNCTION:CBB]]

7, get and set the maximum number of emitter to monitor
Nodejs The number of listeners to the same event is not recommended for more than 10, this can be viewed EventEmitter.defaultMaxListeners as the property can be learned, as follows:

Console.log (eventemitter.defaultmaxlisteners)//Result: 10

Emitter getMaxListeners() Gets the maximum number of listeners through the method and the setMaxListeners(n) method sets the maximum number of listeners, as follows:

var CbA = () =>{},
  CbB = () =>{};
var emitter = new Myemiter ();
Emitter.setmaxlisteners (1);
Emitter.on (' data ', CbA);
Emitter.on (' data ', CbB);
Console.log (Emitter.getmaxlisteners ());

The results of the implementation are as follows:

E:\developmentdocument\nodejsdemo>node Event-example.js
The maximum number of emitter event listeners is: 1
(node:6808) Warning:possible Eventemitter memory leak detected. 2 Data Listener
S added. Use Emitter.setmaxlisteners () to increase limit

As shown above, if the maximum number of listeners is set, the listener for the same event is best not to exceed the maximum, or it is likely to send a memory leak.

The events module introduces this. Hope to help you learn, but also hope that we support the cloud-dwelling community.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.