【问题标题】:TypeError: Cannot read property 'emit' of undefinedTypeError:无法读取未定义的属性“发出”
【发布时间】:2017-06-20 00:45:08
【问题描述】:

问题是每当我尝试触发“this.io.emit”事件时,都会发生 TypeError。它仅在我在“socket.on”块内编写此语句“this.io.emit”时给出,否则,如果我将它写在此块之外,它不会产生错误。

这是调用其他库的主 server.js 文件:

const express = require('express'),
http = require('http'),
socketio = require('socket.io');

class App{

constructor()
{
    this.port =  process.env.PORT || 81;
    this.host = `localhost`;        
    this.app = express();
    this.http = http.Server(this.app);
    this.socket = socketio(this.http);
}
appConfig(){
    new config(this.app);
}
appRoutes(){
    new routes(this.app,this.socket).routesDefault();
}
appDefault(){
    this.appConfig();
    this.appRoutes();
    this.http.listen(this.port,this.host,()=> {
        console.log(`Listening`);
    });
}}

我的服务器端代码是:

'use strict';
class Routes {

constructor(app,socket) {
    this.app = app;
    this.io = socket;
    this.users=[];
}

routesTemplate()
{
    this.app.get('/',function(req,res){
        res.render('index');
    });
}

socketEvents()
{
    this.io.on('connection',(socket) => {
        socket.on('send message',function(data)
        {
            this.io.emit('new message',data);//here the error lies.
        });
    }); 
}
routesDefault()
{
    this.routesTemplate();
    this.socketEvents();
}}  
module.exports = Routes;

我还尝试访问 socket.on 语句中的“this.users.The length”,它生成了相同的 TypeError:无法读取属性长度。我不知道它为什么会发生。请帮我解决这个问题。

客户端:

        <script>
        $(function($){
            var socket = io.connect();
            var $messageForm = $('#send-message');
            var $messageBox = $('#message');
            var $chat = $('#chat');

            $messageForm.submit(function(e){
                e.preventDefault();
                socket.emit('send message',$messageBox.val());
                $messageBox.val("");
            });
            socket.on('new message',function(data){
                $chat.append(data+ "<br/>");
            });
        });
    </script>

【问题讨论】:

    标签: javascript node.js sockets typeerror


    【解决方案1】:

    this 的上下文是您代码中的一个问题。要传递当前上下文,请使用 bindArrow 函数。在 javascript 中,this 的值由你如何调用函数定义,在你的例子中是socket 对象。

    socketEvents()
    {
        this.io.on('connection',(socket) => {
            socket.on('send message',function(data)
            {
                this.io.emit('new message',data);//here the error lies.
            }bind(this));
        }); 
    }
    

    P.S.:已编辑,现在此代码可以正常工作。我想建议以下关于它的帖子。

    What are the differences (if any) between ES6 arrow functions and functions bound with Function.prototype.bind?

    【讨论】:

    • 但是我有另一个完全相似的应用程序,不同之处在于我使用的是 angularJS,如果使用错误的语法“this.io.emit”,它不会出错。这让我大吃一惊。在(javascript和angularJS)中处理“this”有什么区别吗?
    • 你能显示那个代码吗?这取决于代码的编写方式,但据我所知,this 的工作方式相同。
    • 我知道实际的问题只是使用箭头函数和没有绑定 this 的函数。
    【解决方案2】:

    这是因为 this 的上下文对于内部函数是不同的。

    试试:

    socketEvents()
    {
        this.io.on('connection',(socket) => {
            socket.on('send message',function(data)
            {
                socket.emit('new message',data);//here the error lies.
            });
        }); 
    }
    

    【讨论】:

    • 你是对的,但你的答案没有意义,因为它没有提供在 socket.on 中使用“this”的解决方案。它只是提供了一种在我的情况下没有用的替代方式。因为我必须使用“this”关键字(强制)。
    【解决方案3】:

    使用 io.emit() 而不是 socket.broadcast.emit()

    io.on('connection', function(socket){
      socket.broadcast.emit('request', /* */); 
      io.emit('broadcast', /* */); 
      socket.on('reply', function(){ /* */ }); 
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-09
      • 1970-01-01
      • 2020-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-17
      相关资源
      最近更新 更多