Nodejs中关于引入EventEmitter对象的方法的方式

Nodejs中关于引入EventEmitter对象的方法的方式

构造函数中使用如下代码:

events.EventEmitter.call(this);

另外的方式:

util.inherits(appDAO, events.EventEmitter);

这两种方式是否重复?

原始代码如下:

function appDAO(config){
    if(config){
        db_option = config;
    }
    else{
        db_option = new db_config();
    }
    events.EventEmitter.call(this);
    logger.debug(db_option);
    pool = mysql.createPool(db_option);
    //设置mysql连接池单次最大连接数,默认10
    //pool.connectionLimit(10);
    //设置连接池最大请求队列长度,默认0,即不限制.如果设置了则超过长度时getConnection会返回错误
    //pool.queueLimit(0);
    logger.info('init mysql pool');
}
//继承events模块,用于处理消息
util.inherits(appDAO, events.EventEmitter);

外部引用appDAO来调用EventEmitter的方法。

我觉得这其中一个语句是没有必要的,不知道我理解的对不对


8 回复

Node.js 中关于引入 EventEmitter 对象的方法

在 Node.js 中,EventEmitter 是一个非常重要的模块,用于实现事件驱动编程。要使用 EventEmitter 的功能,需要将其引入到自定义的类或对象中。以下是两种常见的方法:

方法一:直接调用 EventEmitter 构造函数

const EventEmitter = require('events');

function appDAO(config) {
    if (config) {
        db_option = config;
    } else {
        db_option = new db_config();
    }
    EventEmitter.call(this); // 直接调用 EventEmitter 构造函数
    logger.debug(db_option);
    pool = mysql.createPool(db_option);
    logger.info('init mysql pool');
}

module.exports = appDAO;

在这个方法中,我们在构造函数内部直接调用了 EventEmitter.call(this),这会使当前实例继承 EventEmitter 的所有方法。

方法二:使用 util.inherits 继承 EventEmitter

const EventEmitter = require('events');
const util = require('util');

function appDAO(config) {
    if (config) {
        db_option = config;
    } else {
        db_option = new db_config();
    }
    logger.debug(db_option);
    pool = mysql.createPool(db_option);
    logger.info('init mysql pool');
}

util.inherits(appDAO, EventEmitter); // 使用 util.inherits 继承 EventEmitter

module.exports = appDAO;

在这个方法中,我们使用了 util.inherits 来继承 EventEmitter,这样就可以使 appDAO 类自动继承 EventEmitter 的所有方法。

两种方法是否重复?

这两种方法本质上都是为了将 EventEmitter 的功能引入到 appDAO 类中,但它们的实现方式不同。

  • 直接调用 EventEmitter.call(this)

    • 这种方法需要在构造函数内部手动调用 EventEmitter.call(this)
    • 这种方法更灵活,可以更好地控制何时初始化 EventEmitter 的功能。
  • 使用 util.inherits

    • 这种方法通过 util.inherits 自动继承 EventEmitter 的所有方法。
    • 这种方法更简洁,但可能会稍微降低代码的灵活性。

示例代码分析

在你的原始代码中,你同时使用了两种方法:

const EventEmitter = require('events');
const util = require('util');

function appDAO(config) {
    if (config) {
        db_option = config;
    } else {
        db_option = new db_config();
    }
    EventEmitter.call(this); // 方法一
    logger.debug(db_option);
    pool = mysql.createPool(db_option);
    logger.info('init mysql pool');
}

util.inherits(appDAO, EventEmitter); // 方法二

实际上,这两种方法不必要同时使用。你可以选择其中一种方法来实现相同的功能。例如,如果你选择使用 util.inherits,那么可以直接去掉 EventEmitter.call(this)

const EventEmitter = require('events');
const util = require('util');

function appDAO(config) {
    if (config) {
        db_option = config;
    } else {
        db_option = new db_config();
    }
    logger.debug(db_option);
    pool = mysql.createPool(db_option);
    logger.info('init mysql pool');
}

util.inherits(appDAO, EventEmitter); // 只使用这种方法

module.exports = appDAO;

总结来说,两种方法都可以实现相同的效果,但推荐使用 util.inherits 方法,因为它更简洁且易于维护。


Example:

function O(){
  EventEmitter.call(this);

}

util.inherits(O,EventEmitter);

all should use.


签名: 交流群244728015 《Node.js 服务器框架开发实战》 http://url.cn/Pn07N3

只用其中一句效果也是一样吧?

是有点怪, 不过看源码还是能理解… .call 只是绑定方法, 而 .inherents.prototype 指向父类:

coffee> console.log util.inherits.toString()
function (ctor, superCtor) {
  ctor.super_ = superCtor;
  ctor.prototype = Object.create(superCtor.prototype, {
    constructor: {
      value: ctor,
      enumerable: false,
      writable: true,
      configurable: true
    }
  });
}

还是没说明白啊~ 如果单个使用inherents不是就可以了吗?

-. - 我都是inherits继承的

also correct, but best both. because need instanceof sometimes.

EventEmitter new version is corrent, old version must both.


签名: 交流群244728015 《Node.js 服务器框架开发实战》 http://url.cn/Pn07N3

在Node.js中引入EventEmitter对象主要有两种方式:直接调用其构造函数和使用util.inherits方法。这两种方式并不重复,而是服务于不同的目的。

示例代码

const EventEmitter = require('events');
const util = require('util');

function appDAO(config) {
    if (config) {
        db_option = config;
    } else {
        db_option = new db_config();
    }
    this.init(config); // 直接调用初始化方法
    logger.debug(db_option);
    pool = mysql.createPool(db_option);
    logger.info('init mysql pool');
}

// 使用util.inherits继承EventEmitter
util.inherits(appDAO, EventEmitter);

// 或者直接调用EventEmitter的构造函数
// 注意这种方式需要在构造函数内部调用EventEmitter.call(this),但通常我们会选择util.inherits
// appDAO.prototype.__proto__ = EventEmitter.prototype;

appDAO.prototype.init = function(config) {
    EventEmitter.call(this); // 只在直接调用构造函数的情况下需要
};

module.exports = appDAO;

解释

  • 直接调用构造函数 (events.EventEmitter.call(this);):这种方式主要用于在构造函数内部将当前对象实例化为EventEmitter的一个实例。这通常是在没有使用util.inherits的情况下完成继承。

  • 利用util.inherits (util.inherits(appDAO, EventEmitter);):这是更常见的做法,它会将EventEmitter的方法添加到appDAO的原型上,从而允许appDAO的实例可以直接访问EventEmitter的方法。这种方式更加推荐,因为它更为简洁且避免了潜在的错误。

总结

在这段代码中,util.inherits(appDAO, EventEmitter); 是必须的,因为它是实现appDAO类继承EventEmitter的主要方式。而events.EventEmitter.call(this); 则是在构造函数内部手动将实例作为EventEmitter的实例进行初始化的一种方式,在util.inherits存在的情况下,这部分代码是多余的,可以省略。

回到顶部