如何在Javascript中包装“方法”?

问题描述

我无法绕开eventEmitter2库的.on方法来传递我的自定义变量。

  • 尝试#1

    let qHandler = new EventEmitter2({ wildcard: true });
    const qHandlerWrapper = (queueName)=>{  
        qHandler.on = (eventName,callbackFunc)=>{
            return qHandler.on(`${queueName}.${eventName}`,callbackFunc)
        }
        return qHandler
    }
    

    此处代码进入无限递归调用

  • 尝试#2-克隆qHandler对象

    let qHandler = new EventEmitter2({ wildcard: true });
    const qHandlerOnMain = require('lodash/clonedeep')(qHandler)
    const qHandlerWrapper = (queueName)=>{
        qHandler.on = (eventName,callbackFunc)=>{
            return qHandlerOnMain.on(`${queueName}.${eventName}`,callbackFunc)
        }
        return qHandler
    }
    
    • 这稍微解决了我的问题,但无法使用qHandler的其他方法,例如onAny

    原因:我已将所有事件注册qHandlerOnMain对象下,并返回另一个-qHandler, 导致qHandler.onAny不能找不到查找在qHandler注册的任何事件。

解决方法

我不确定您在这里实际要做什么,但是使用私有库方法不是一个好主意,因为我们可能会在不久的将来更改其签名。此外,这绝对是修复EventEmitter2原型的错误方法。这将影响所有其他实例。许多其他模块使用EventEmitter2。您应该将EventEmitter2子类化,以出于自己的目的更改on方法的实现。 但是根据您的代码:

const originalOn= EventEmitter2.prototype.on;

const qHandlerWrapper = (queueName)=>{        
    // this is a bad idea!!!
    EventEmitter2.prototype.on = function(type,listener,options) {
    // wildcard emitter accepts an array as event path
        return originalOn.call(this,[queueName,type],options);
    };

    return qHandler;
}

由于我不了解您的需求,因此我无法提供更合适的解决方案。为什么要克隆Eventemitter实例,为什么要将queueName绑定到on方法?

,

最后,我必须在eventEmitter2 prototype

上添加包装器代码
let qHandler = new EventEmitter2({ wildcard: true });
  
const qHandlerWrapper = (queueName)=>{  
    EventEmitter2.prototype.on = function(type,options) {
      return this._on(`${queueName}.${type}`,false,options);
    };
    return qHandler;
}