无法在nodejs模块中使用socket.io emit函数

时间:2018-03-28 16:39:21

标签: javascript node.js socket.io

我的代码如下:

我有一个socketAPI模块,可以处理应用程序的所有套接字流量:

var io = new socketIoServer();
var socketApi = {};
socketApi.io = io;

io.on('connection', function (client) {
    const SetupHandler = require ('./socket_handlers/setup-handler.js');
    setupHandler = new SetupHandler(client, arg1, arg2);
    setupHandler.bind();
}

然后在设置处理程序中我得到以下代码:

function SetupHandler(client,arg1,arg2) {
    this.client = client;
    socketApi.setups[lobby.id] = new Setup(lobby, scenario_id);
    this.setup = socketApi.setups[lobby.id];
    this.client.emit("test");                       //this works
}
SetupHandler.prototype.requestGameSetup = function(){
    // do stuff
    this.client.emit("test");  //doesnt work

};
SetupHandler.prototype.bind = function(){
    this.client.on('request_game_setup', this.requestGameSetup);
}
module.exports = SetupHandler;

它给了我以下错误:

/home/markus/WebstormProjects/penquest/socket_handlers/setup-handler.js:32
this.client.emit("test");
            ^

TypeError: this.client.emit is not a function
at Socket.SetupHandler.requestGameSetup (/home/markus/WebstormProjects/penquest/socket_handlers/setup-handler.js:32:17)
at Socket.emit (events.js:180:13)
at /home/markus/WebstormProjects/penquest/node_modules/socket.io/lib/socket.js:513:12

这里的想法是每个客户端连接有一个SetupHandler处理所有事件,你有什么想法我能做到这一点吗?

2 个答案:

答案 0 :(得分:0)

解决方案:

SetupHandler.prototype.requestGameSetup = () => {
// do stuff
this.client.emit("test");  //doesnt work };

使用=>运算符将此范围放入原型中。

答案 1 :(得分:0)

问题是你在这行代码上失去了this的价值:

this.client.on('request_game_setup', this.requestGameSetup);

将其更改为:

this.client.on('request_game_setup', this.requestGameSetup.bind(this));

当你通过this.requestGameSetup时,就像你这样做:

let fn = this.requestGameSetup;
this.client.on('request_game_setup', fn);

此时,fn只是对requestGameSetup函数的引用,并且在没有对象引用的情况下调用它,因此this值不是您想要的。您可以使用.bind()将所需的this值绑定到它。

你也不能直接传递它:

this.client.on('request_game_setup', () => {
    this.requestGameSetup();
});

在这里,您使用胖箭头功能定义为您保留this的值,以便您可以调用this.requestGameSetup()。但是,我更喜欢使用.bind(),因为它似乎更直接地执行您希望它做的事情。