在构造函数中定义时未定义的类变量

时间:2014-10-14 23:17:00

标签: javascript coffeescript

刚开始使用CoffeeScript并且碰壁了。在下面的代码中,我构造了WebSocketServer,其中一个数字作为第一个参数,一个函数作为第二个参数。当代码运行并且websocket收到消息时,@msgHandler现在神奇地未定义。我尝试通过将变量handler设置为@msgHandler来解决此问题,但最终也未定义。如果有人有任何想法,我很乐意听到他们,谢谢!

main.coffee

#Used to communicate with browser interface
webSocketServ = new sio.WebSocketServer Sauce.Server.WebSocketPort, (data, socketId) ->
    try
        json = JSON.parse(data)
        msgType  = json.msgType
    catch error
        return

    if (this.isAuthed(socketId))
        switch msgType
            when "auth"

            else
                io.websocket 'TODO: ' + cmd        
    else
        if msgType is 'auth'
            token = json.token

socket.coffee

class WebSocketServer
    constructor: (@port, @msgHandler) ->
        @webSockets = []
        @handlers = {}
        @test = []
        @authedSockes = []
        @listen(@port);
        console.log @msgHandler #msgHandler is defined here as [ Function ]

    listen: (port) ->
        @wsServ = engine.listen port
        @wsServ.on 'connection', @onConnect
        io.socket "WebServer socket started on port #{port}"

    onConnect: (client) ->
        io.websocket 'New connection with id of ' + client.id

        handler = @msgHandler #@msgHandler is undefined here?

        client.on 'message', (data) ->
            handler data, client.id
            io.websocket '[' + this.id + '] ' + JSON.stringify(data)

        client.on 'close', ->
            io.websocket '[' + this.id + '] Disconnect'

        client.on 'error', (err) ->
            io.websocket "IO error: " + err

编译socket.coffee

  WebSocketServer = (function() {
    function WebSocketServer(port, msgHandler) {
      this.port = port;
      this.msgHandler = msgHandler;
      this.webSockets = [];
      this.handlers = {};
      this.test = [];
      this.authedSockes = [];
      this.listen(this.port);
      console.log(this.msgHandler);
    }

    WebSocketServer.prototype.listen = function(port) {
      this.wsServ = engine.listen(port);
      this.wsServ.on('connection', this.onConnect);
      return io.socket("WebServer socket started on port " + port);
    };

    WebSocketServer.prototype.onConnect = function(client) {
      var handler;
      io.websocket('New connection with id of ' + client.id);
      handler = this.msgHandler;
      client.on('message', function(data) {
        handler(data, client.id);
        return io.websocket('[' + this.id + '] ' + JSON.stringify(data));
      });
      client.on('close', function() {
        return io.websocket('[' + this.id + '] Disconnect');
      });
      return client.on('error', function(err) {
        return io.websocket("IO error: " + err);
      });
    };

    WebSocketServer.prototype.isAuthed = function(socketId) {
      return __indexOf.call(this.authedSockets, user) >= 0;
    };

    WebSocketServer.prototype.authSocket = function(socketId) {
      this.authedSockets.push(socketId);
      return io.websocket('Authed socket with ID of ' + socketId);
    };

    WebSocketServer.prototype.deauthSocket = function(socketId) {
      return this.authedSockets = this.authedSockets.filter(function(word) {
        return word !== socketId;
      });
    };

    return WebSocketServer;

  })();

1 个答案:

答案 0 :(得分:3)

它不是未定义的类变量,您的意思是您无法访问实例属性。它是由公共this context issue in callbacks引起的 - 你不能只传递一个方法并期望它知道实例。

幸运的是,使用fat arrow syntax进行方法定义和其他回调可以在CS中轻松修复:

    onConnect: (client) =>
#                       ^^
        io.websocket 'New connection with id of ' + client.id

        handler = @msgHandler # @ is now the expected instance

        client.on 'message', (data) =>
#                                   ^^
            handler data, client.id
            io.websocket '[' + @id + '] ' + JSON.stringify(data)
#                              ^ or did you mean to use `client.` here?

        client.on 'close', =>
#                          ^^
            io.websocket '[' + @id + '] Disconnect'

        client.on 'error', (err) ->
            io.websocket "IO error: " + err

一种不同的(可能更好的)方法可能是让你的WebSocketServer从引擎的类继承,而不是围绕它构建一个包装器。由于通常在服务器实例上调用所有回调,因此您可以直接访问属性而无需绑定回调。