简体   繁体   English

Node.JS EventEmitter Listener必须是一个函数

[英]Node.JS EventEmitter Listener Must be a Function

I am getting an error when attempting to setup listeners within a function. 尝试在函数中设置侦听器时出错。 I have reviewed other code that this works for, but can't seem to get it to work for my purposes. 我已经审查了其中适用的其他代码,但似乎无法使其适用于我的目的。

This is a simplified version of what I am attempting to get done. 这是我试图完成的简化版本。

var ticketGenerator = function(){
    var self = this;
    console.log('ticket generator');
    var rows = "";
    this.emit("getQueue")

    var _getQueue = function(){
    console.log('Getting Queue');
    var connection = mysql.createConnection({
        //Connection Data
    }); 
    connection.connect();
    connection.query("SELECT * FROM `queue` WHERE `run` = 0 ORDER BY `queueID` ASC LIMIT 1", function(err, rows, fields){
        if(err){
            //self.emit("error", "Unable to get data from the database.")
            console.log(err);
        }
        else if(typeof rows[0] == "undefined"){
            console.log("Waiting to run again.");
            connection.end();
            setTimeout(function(){ticketGenerator()}, 60000);
        }
        else{
            console.log("Passing Ticket Data");
            self.emit("newTicketData", rows);
            connection.end();
        }
    })
    };

    this.on("getQueue", _getQueue);
}

I cannot get it to run the function for _getQueue. 我无法让它为_getQueue运行该函数。 When I put in the listener _getQueue() it will run the function, but throws an error (TypeError: listener must be a function). 当我放入监听器_getQueue()时,它将运行该函数,但抛出一个错误(TypeError:listener必须是一个函数)。 I'm not sure what I am doing wrong as I have seen other code written in this way that is working. 我不确定我做错了什么,因为我已经看到以这种方式编写的其他代码正在工作。

I have verified that I have the listeners setup with this.on('newListener' . . . ). 我已经验证我使用this.on设置了监听器('newListener'...)。 I assume that since I can get it to call the function when changing the name on the listener that the emitter is doing it's job as well. 我假设因为我可以在更改侦听器上的名称时调用该函数,发射器也在执行它的工作。

Note that this ticketGenerator function is being called from another file using requires. 请注意,使用requires从另一个文件调用此ticketGenerator函数。 I don't know if this will affect the solution for this issue, but figured that detail may be important. 我不知道这是否会影响这个问题的解决方案,但认为细节可能很重要。

---------------EDIT---------------- I ended up figuring this out after I posted this. ---------------编辑----------------我在发布之后最终搞清楚这一点。 I needed to call a constructor for these events to go through. 我需要调用构造函数来完成这些事件。 The code looks like the following. 代码如下所示。

events.EventEmitter.call(this);

I couldn't answer my own question due to rep, but will update the answer area when I can. 由于代表我无法回答我自己的问题,但是我会尽快更新答案区域。

Here's a solution to different of your problems: 这是解决您不同问题的方法:

  • In your sample, self will be associated with the window or global namespace. 在您的示例中,self将与窗口或全局命名空间相关联。 There's no way you can access your EventEmitter using this. 你无法使用它来访问你的EventEmitter。
  • You emit the first getQueue event before attaching a listener. 在附加侦听器之前发出第一个getQueue事件。 You must instantiate your TicketGenerator and then emit the first getQueue to get the wheel started. 您必须实例化TicketGenerator,然后发出第一个getQueue以启动方向盘。
  • In your timeout, just need to emit a new getQueue to retry, no need to instantiate the TicketGenerator again. 在你的超时中,只需要发出一个新的getQueue来重试,不需要再次实例化TicketGenerator。

Hope this helps. 希望这可以帮助。

TicketGenerator = function() {
    var self = this;
    console.log('ticket generator');
    var rows = "";

    EventEmitter.call(this);

    var _getQueue = function() {
        console.log('Getting Queue');
        var connection = mysql.createConnection({
            //Connection Data
        }); 
        connection.connect();
        connection.query("SELECT * FROM `queue` WHERE `run` = 0 ORDER BY `queueID` ASC LIMIT 1", function(err, rows, fields){
            if(err){
                //self.emit("error", "Unable to get data from the database.")
                console.log(err);
            }
            else if(typeof rows[0] == "undefined"){
                console.log("Waiting to run again.");
                connection.end();
                setTimeout(function(){
                    self.emit('getQueue');
                }, 60000);
            }
            else {
                console.log("Passing Ticket Data");
                self.emit("newTicketData", rows);
                connection.end();
            }
       });
    }

    this.on("getQueue", _getQueue);
};

// Instantiate the ticket generator and initiate the first queue retrieval
var ticketGenerator = new TicketGenerator();
ticketGenerator.emit('getQueue');

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM