我只是想证实我的怀疑。
我偶然发现了一篇建议以下列方式使用Socket.io的文章:
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
});
});
我觉得以下会更好地利用资源:
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
}
我的感觉是,虽然处理connection
事件的匿名函数只在内存中创建一次,但是处理action1
,action2
和disconnect
的匿名函数在内存中为每个套接字连接创建。第二种方法的问题是socket
已不在范围内。
首先,我怀疑函数的创建是真的吗?其次,如果有这样的方法可以在命名函数的范围内获得socket
吗?
答案 0 :(得分:5)
使用闭包有助于保持范围清洁:
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
问题:
首先,我怀疑函数的创建是真的吗?
是。上面的闭包方法可以防止这种情况,回调函数只创建一次。另外:所有人都看到了正确的父范围。
其次,如果有办法让
socket
在命名函数的范围内?
socket
将在回调中以this
的形式提供。
答案 1 :(得分:1)
你是对的,为每个连接创建了匿名方法 - 如果你不需要范围,那么第二种方法确实避免了这种情况。如果您需要套接字范围,则没有真正的方法可以避免它。如果您希望将方法保持在外部(出于某些其他原因)并仍然保持范围,您可以始终:
//...
socket.on('action1', function(){
action1.apply( socket, arguments );
} );
//... and so forth.
但是你要回到为每个连接创建一个方法签名,所以我不确定你会获得什么。