javascript - 为什么在传递/公开 EventEmitter 的 on 函数时需要包装它?

标签 javascript node.js eventemitter

我的应用程序使用几种不同的机制与设备进行通信,例如串行(即USB CDC/虚拟COM端口)和TCP(即telnet),并且我尝试以更高的方式封装/隐藏/抽象此功能-level 接口(interface),以便使用这些接口(interface)的代码的其他部分不关心正在使用哪种机制。

在本例中,我有 serial.jstcp.js,它们各自导出一个名为 connect 的函数,该函数返回一个带有 on: function() { ... } 属性,我想要将其连接到其内部 EventEmitter 实例。 (我认为我不应该公开整个对象,因为这可能允许其他代码调用发出并产生难以调试的问题。)

让我困惑的是,如果我只是返回 { on: emitter.on } 那么回调似乎永远不会被调用,但是如果我返回 { on: function(a, b ) { return 发射器.on(a,b); } 它工作正常。我觉得这与闭包/作用域或符号发射器解析的时间有关,但这与我之前遇到的有关这些主题的其他问题不同。有人可以帮助我理解这里发生的事情使这两行相似的代码如此不同吗?

"use strict";

const net = require('net');
const EventEmitter = require('events');
const ConnectionEventNames = require('./events.js');


function connect(settings) {
    // ... (validates settings) ...
    const emitter = new EventEmitter();

    const socket = net.connect({
        host: settings.host,
        port: settings.port
    }, () => {
        emitter.emit(ConnectionEventNames.connected);
    });

    socket.on('data', (data) => {
        emitter.emit(ConnectionEventNames.received_data, data);
    });
    socket.on('error', (error) => {
        emitter.emit(ConnectionEventNames.error, error);
    });
    socket.on('end', () => {
        emitter.emit(ConnectionEventNames.disconnected);
    });
    socket.setNoDelay(settings.setNoDelay);

    return {
        // FIXME: why didn't this work the way I initially wrote it? (next line)
        on_original: emitter.on,
        on: function(eventName, listener) {
            return emitter.on(eventName, listener);
        },
        // ...
    };
}


module.exports = {
    connect
};

最佳答案

像这样传递实例的原型(prototype)函数时的问题是上下文丢失。 emitter.on 并未隐式绑定(bind)到 emitter,它只是一个普通函数。如果没有 emitter 上下文,.on() 实现中的 this 将不会指向您所期望的内容。

通常情况下,您会很快看到异常抛出,因为大多数原型(prototype)函数通常会假定有效的上下文,因此尝试访问 this 上的特定属性,但是 EventEmitter 有点特殊之处在于它检查是否缺少内部属性并在缺少时创建它们。因此,它将在您执行函数的任何上下文(全局或其他)上创建这些属性。

关于javascript - 为什么在传递/公开 EventEmitter 的 on 函数时需要包装它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35946806/

相关文章:

node.js - AWS服务器上的 sails 升力出现问题

javascript - child 更新 parent 的 'Angular way' 是什么?

javascript - 来自另一个组件的 Angular2 调用函数

javascript - 使用 Web Audio API 的音频 react 视觉

javascript - 基于另一个 javascript 文件定义带参数的函数

javascript - $broadcast 不从服务中触发 (AngularJS)

angularjs - 如何在 Express 中启用 HTML5 模式而不破坏 NodeMailer?

node.js - Node.js Web服务器中的 Electron 类 Node 集成

javascript - 无法读取 CKEditor ASP.NET 的 null 属性 'unselectable'

Angular 2 : using a service to broadcast an event