Eficiencia con devoluciones de llamada de JavaScript

Solo quería confirmar una sospecha mía.

Me topé con un artículo que recomendaba usar Socket.io de la siguiente manera:

var app = require('express').createServer() var io = require('socket.io').listen(app); app.listen(8080); // Some unrelated stuff io.sockets.on('connection', function (socket) { socket.on('action1', function (data) { // logic for action1 }); socket.on('action2', function (data) { // logic for action2 }); socket.on('disconnect', function(){ // logic for disconnect }); }); 

Siento que lo siguiente sería un mejor uso de los recursos:

 var app = require('express').createServer() var io = require('socket.io').listen(app); app.listen(8080); // Some unrelated stuff io.sockets.on('connection', function (socket) { socket.on('action1', action1); socket.on('action2', action2); socket.on('disconnect', disconnect); }); function action1(data) { // logic for action1 } function action2(data) { // logic for action2 } function disconnect() { // logic for disconnect } 

Mi sensación es que aunque la función anónima que maneja el evento de connection solo se crea en la memoria una vez, las funciones anónimas que manejan action1 , action2 y disconnect se crean en la memoria para cada conexión de socket. El problema con el segundo enfoque es que el socket ya no está dentro del scope.

Entonces, en primer lugar, ¿es cierta mi sospecha sobre la creación de funciones? Y en segundo lugar, si es así, ¿hay una manera de obtener un socket en el scope de las funciones nombradas?

El uso de un cierre ayuda a mantener el scope limpio:

 io.sockets.on('connection', function () { function action1(data) { // logic for action1 } function action2(data) { // logic for action2 } function disconnect() { // logic for disconnect } return function (socket) { socket.on('action1', action1); socket.on('action2', action2); socket.on('disconnect', disconnect); } }()); // <- note the immediate function call 

A tus preguntas:

Entonces, en primer lugar, ¿es cierta mi sospecha sobre la creación de funciones?

Sí. El enfoque de cierre anterior evita esto, las funciones de callback se crean solo una vez. Más: todos ven los scopes correctos de los padres.

Y en segundo lugar, si es así, ¿hay una manera de obtener un socket en el scope de las funciones nombradas?

El socket estará disponible como this en las devoluciones de llamada.

Tienes razón, que los métodos anónimos se crean para cada conexión, y si no necesitas un scope, entonces el segundo método evita eso. Si necesita el scope del zócalo, no hay manera real de evitarlo. Si desea mantener los métodos externos (por alguna otra razón) y aún mantener el scope, siempre podría:

 //... socket.on('action1', function(){ action1.apply( socket, arguments ); } ); //... and so forth. 

Pero eso hace que vuelvas a crear una firma de método para cada conexión, así que no estoy seguro de lo que ganarías.