如何管理多个监听器?

How to manage multiple listeners?

我对听众有意见。我在自己开发的节点中的 http 侦听器中有多个输入。我使用了这样的东西:

...    
server.on(‘connection’, function(){
        node.on(‘input’, function(){
            // something to manage messages
        });
    });
...

我想选择何时停止侦听器(例如,当它找到特定 msg.payload 时)。我尝试了“node.once(..”、“node.removeListener(..”但什么也没有。你能帮我吗?谢谢。

编辑

所有代码:

var server = http.createServer((request, response) => {
    if (request.url == '/log' || request.url == '/log2'){
        let body = [];
        request.on('error', (err) => {
            console.error(err);
        }).on('data', (chunk) => {
            body.push(chunk);
        }).on('end', () => {
            body = Buffer.concat(body).toString();

            response.on('error', (err) => {
                console.error(err);
            });

            response.statusCode = 200;
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Content-Type", "text/html");

            msg = {_msgid:"1c6db704.811319", topic:request.url ,payload: true};
            node.send(msg);


            function inputListener(msg) {
                console.log(msg.topic + " " + request.url);
                if (msg.topic == request.url)
                    response.end(JSON.stringify(msg.payload));

                //node.removeListener('input', inputListener);
            }
            node.on('input', inputListener);

        });
    } else {
        response.statusCode = 404;
        response.end();
    }
}).listen(8088);

编辑 2

使用这个技巧似乎有效:

            function inputListener(msg) {
                if (msg.topic == request.url)
                    response.end(JSON.stringify(msg.payload));
                else
                    node.once('input', inputListener);
            }
            node.once('input', inputListener);

node.removeListener() 如果你正确使用它会工作得很好,所以我假设你没有正确使用它。要正确使用 .removeListener() 来删除一个特定的侦听器,您必须将您最初收听的消息和相同的函数引用传递给它。这意味着您不能像显示的那样使用匿名函数引用:

相反,您可以这样做:

server.on('connection', function(){
    function inputListener(data) {
        // something to manage messages
        if (someCondition) {
            // if some condition is met, then remove this specific listener
            node.removeListener('input', inputListener);
        }
    }
    node.on('input', inputListener);
});

这里的代码创建了一个本地函数(每次调用 connection 处理程序时该函数都是唯一的),然后将其与 .on() 一起使用。这样,当您想要删除该特定侦听器时,您就可以将完全相同的函数引用传递给 .removeListener() 。可能值得回顾 doc for .removeListener().

node.once() 也有它自己的特定目的。它所做的是在下次事件触发后自动删除事件侦听器。如果这正是您想要的情况,那将非常方便。但是,如果您想测试某些条件并且仅在满足该条件时删除事件处理程序并且有时需要查看事件的多次出现,那么您不能为此使用 .once()

P.S。您的问题在您的事件名称周围包含非法类型的引号。这在 Javascript 中不起作用。您永远不应该在执行此类处理的文字处理器中编辑代码。始终使用文本编辑器。


现在您已经包含了更多实际代码,您似乎遇到了并发问题,因为您对所有请求使用了相同的 node 对象,因此您无法分辨哪个 input 事件属于哪个请求。您将需要解决该问题。

有很多方法可以做到这一点,但这是一种方法。您将需要更改 node 对象,以便它接收您发送的唯一 ID,并 returns 它随响应返回,这样您就可以知道哪个响应与哪个请求对应。

const unique = require('node-unique');

var server = http.createServer((request, response) => {
    if (request.url == '/log' || request.url == '/log2'){
        let body = [];
        request.on('error', (err) => {
            console.error(err);
        }).on('data', (chunk) => {
            body.push(chunk);
        }).on('end', () => {
            body = Buffer.concat(body).toString();

            response.on('error', (err) => {
                console.error(err);
            });

            response.statusCode = 200;
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Content-Type", "text/html");

            // generate unique id for this request
            let uniqueID = unique();
            msg = {_msgid:"1c6db704.811319", topic:request.url ,payload: true, id: uniqueID};
            node.send(msg);

            function inputListener(msg) {
                // ignore if this is not our msg
                if (msg.id === uniqueID) {
                    console.log(msg.topic + " " + request.url);
                    if (msg.topic == request.url)
                        response.end(JSON.stringify(msg.payload));

                    node.removeListener('input', inputListener);
                }
            }
            node.on('input', inputListener);
        });
    } else {
        response.statusCode = 404;
        response.end();
    }
}).listen(8088);