Regular study notes, including ES6, Promise, Node.js, Webpack, HTTP Principles, Vue buckets, and possibly more Typescript, Vue3, and common interview questions.


The Events module

Reference website events event trigger | Node. Js

The Events module is the most important module of Node. It provides an attribute EventEmitter, whose core is EventEmitter and event listener.

Most modules in Node inherit from the Events module.

  • EventsModules are Node pairsPublish and subscribe model(publish/subscribe). An object passes a message to another object through this module.
  • This module passesEventEmitterProperty, which provides a constructor. An instance of the constructor hasonMethod that can be used to listen for a specified event and trigger a callback function.
  • Any object can publish the specified event, byEventEmitterThe on method of the instance listens.

Publish and subscribe model

Check out my previous blog post on the publish and subscribe model.

In terms of the publish-subscribe model in Events, there are a few common approaches to it.

  • The subscribe method:onMethods are used to subscribe to events, which correspond to methods in a one-to-many relationship.
  • Release method:emitThe event used to execute the subscription.
  • unsubscribe:offMethod to remove the corresponding event listener.
  • Subscribe to a:onceBind events Automatically deletes subscribed events when executed.

On and emit

The first argument to the on method is used to set the class name, and the second argument is also a function that accepts arguments passed in when publishing.

The first argument to the emit method is the class name, followed by arguments passed into the on method function.

For details on how to use ON and EMIT, see the simple Demo below.

const EventEmitter = require('events');
// Create a custom constructor
function Cat() {}
// Stereotype inheritance requires instance invocation of inheritance methods
Object.setPrototypeOf(Cat.prototype, EventEmitter.prototype);
let cat = new Cat();
const sleep = (a, b) = > {
    console.log(a, 'sleep');
};
const eat = (a, b) = > {
    console.log(b, 'eat');
};
cat.on('cat', sleep)
cat.on('cat', eat)
setTimeout(() = > {
  	// Mustache eats
  	// Little Fat fairy sleep
    cat.emit('cat'.Little Fat Fairy.'Moustache')},1000);
Copy the code

Now we can implement a set of on and EMIT methods.

function EventEmitter() {
    this._event = {}
}
/ / on the way
EventEmitter.prototype.on = function (eventName, callBack) {
    if (!this._event) {
        this._event = {}
    }
    if (this._event[eventName]) {
        this._event[eventName].push(callBack) EventName :[fn1,fn2]}
    } else {
        this._event[eventName] = [callBack]; EventName :[fn1]}}}/ / emit method
EventEmitter.prototype.emit = function (eventName, ... args) {
    this._event[eventName].forEach(fn= >{ fn(... args) }); }Copy the code

off

The first argument to the off method is used to set the class name, and the second argument is passed to the function callback that needs to be removed.

// ...
setTimeout(() = > {
  	// Mustache eats
  	// Little Fat fairy sleep
    cat.emit('cat'.Little Fat Fairy.'Moustache')
  	cat.off('cat', sleep);
  	// Mustache eats
    cat.emit('cat'.Little Fat Fairy.'Moustache')},1000);
Copy the code

So we can sort of figure out, remove the function that’s the same as the function that we passed in, and we quickly came up with the filter method.

/ / off method
EventEmitter.prototype.off = function (eventName, callBack) {
    if (this._event && this._event[eventName]) {
        this._event[eventName] = this._event[eventName].filter(
          fn= >fn ! == callBack && fn.c ! == callBack// fn.c refer to the once method below)}}Copy the code

once

The first argument to the once method sets the class name, and the second argument passes in a function callback that needs to be executed only once.

// ...
const demolition =() = > {
    console.log('open house');
}
cat.once('cat', demolition)
setTimeout(() = > {
  	/ /... dealer
    cat.emit('cat'.Little Fat Fairy.'Moustache')},1000);
Copy the code

This way we can implement this method based on the previous implementation of on and off.

/ / once method
EventEmitter.prototype.once = function (eventName, callBack) {
    const one = () = > {
        callBack();
        this.off(eventName, one);
    }
    this.on(eventName, one);
}
Copy the code

It looks as if there is nothing wrong with this method, and everything is executed correctly.

But in one particular case, something went wrong.

That would be if we removed it with the off method before executing the once method.

The method we implemented does not fulfill this requirement, so we need to make some changes to the once method (which is already handled by the off method).

Add a custom property to “cache” the function.

EventEmitter.prototype.once = function (eventName, callBack) {
    const one = () = > {
        // ...
    }
    one.c = callBack; // Define an attribute
    // ...
}
Copy the code

So we implement the once method.

This article was created by Mo Xiaoshang. If there are any problems or omissions in the article, welcome your correction and communication. You can also follow my personal site, blog park and nuggets, AND I will upload the article to these platforms after it is produced. Thank you for your support!