Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/36.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在Socket.io事件中重用处理程序/回调的正确方法是什么?这是否重要?_Javascript_Node.js_Sockets_Socket.io - Fatal编程技术网

Javascript 在Socket.io事件中重用处理程序/回调的正确方法是什么?这是否重要?

Javascript 在Socket.io事件中重用处理程序/回调的正确方法是什么?这是否重要?,javascript,node.js,sockets,socket.io,Javascript,Node.js,Sockets,Socket.io,我试图从我的socket.on()事件中排除匿名回调函数,原因有两个: 它使代码更易于阅读和记录 我相信它可以更有效地利用内存 由于第一个原因更多的是个人偏好,我将不讨论它——尽管我肯定有兴趣看到风格指南和/或一般建议 第二个原因是,我看到socket.io使用的唯一方式如下: var io = require('socketio'); io.on('connection', function(socket) { socket.on('event', function(data) {

我试图从我的
socket.on()
事件中排除匿名回调函数,原因有两个:

  • 它使代码更易于阅读和记录
  • 我相信它可以更有效地利用内存
  • 由于第一个原因更多的是个人偏好,我将不讨论它——尽管我肯定有兴趣看到风格指南和/或一般建议

    第二个原因是,我看到socket.io使用的唯一方式如下:

    var io = require('socketio');
    
    io.on('connection', function(socket) {
    
        socket.on('event', function(data) {
            // logic goes here
            socket.emit('different event', differentData);
        });
    });
    
    var sockets = {}
    
    io.on('connection', function(socket) {
        socket.on('login', login.bind(socket));
        socket.on('get information', getInformation);
    });
    
    function login(data) {
        // logic goes here
    
        // Save the socket to a persistent object
        sockets[data.userId] = this;
    
        this.emit('logged in', loginData);
    });
    
    function getInformation(data) {
        // authentication, db access logic goes here
    
        // Avoid binding by using previously stored socket
        sockets[data.userId].emit('got information', infoData);
    });
    
    这可以很好地工作,但我相信匿名函数是为每个传入连接实例化的

    我将通过以下几点来考虑这一点:

    io.on('connection', function(socket) {
    
        socket.on('event', eventHandler);
    
        function eventHandler(data) {
            // logic goes here
            socket.emit('different event', differentData);
        });
    });
    
    不过,这似乎仍然会为每个新连接创建一个“eventHandler”实例

    我目前尝试将其分解如下:

    var io = require('socketio');
    
    io.on('connection', function(socket) {
    
        socket.on('event', function(data) {
            // logic goes here
            socket.emit('different event', differentData);
        });
    });
    
    var sockets = {}
    
    io.on('connection', function(socket) {
        socket.on('login', login.bind(socket));
        socket.on('get information', getInformation);
    });
    
    function login(data) {
        // logic goes here
    
        // Save the socket to a persistent object
        sockets[data.userId] = this;
    
        this.emit('logged in', loginData);
    });
    
    function getInformation(data) {
        // authentication, db access logic goes here
    
        // Avoid binding by using previously stored socket
        sockets[data.userId].emit('got information', infoData);
    });
    
    这是可行的,但我相信bind()只是创建了另一个函数,不管怎样,它破坏了在
    连接中不包含
    登录
    回调的任何真正好处

    至于其他处理程序,似乎需要一个持久化对象,这一点可以从下面的例子中得到证明。由于我计划收听大量的事件,因此将回调从
    连接中拉出似乎是最好的方法。bind可能会在每次调用时创建一个新函数,但在这种情况下,每个连接只调用两次,而不是10-20次。我想,对于成千上万的客户来说,这会有所不同,但我不确定


    因此,总而言之,这是一种正确的方法,还是我应该使用一种更好的方法?或者,这只是另一种过早优化的情况吗?

    这是过早优化。每次都会创建函数(然后GCed),但对于小函数来说,这并不重要,它们很便宜,V8擅长优化它们。我还建议使用命名函数表达式,例如:
    io.on('connection',function-onConnection(socket){…})它们在堆栈跟踪中显示它们的名称。需要考虑的一件事是,创建一个新的函数实例是否实际上是一件昂贵的事情。请记住,创建一个新函数对象并不一定意味着代码被复制-运行时可以利用代码不变的事实,并在实例之间共享它。bind()每次都会创建一个新函数。如果只使用纯函数,那么它们将完全可重用。不过,报告和维护命名函数仍然更好,因此仅出于这个原因,您就应该保持代码的改进。此外,只要一个函数与另一个已经解析的函数相同,内部函数就可以重复使用,而不会重复使用;这甚至适用于调用中定义的Anon,只要它们不使用闭包。有趣的思想食粮。谢谢