Nodejs - 如何使函数只执行一次?

4

我有一个简单的聊天应用程序,利用了socket.io和express框架,以下是部分代码:

var app = express.createServer();
var socket = io.listen(app);

var store = new express.session.MemoryStore;
app.use(express.cookieParser());
app.use(express.session({ 
    secret: 'something', 
    store: store, 
    cookie: { 
        maxAge: 60*60*24*30*1000
    }
}));

app.get('/', function(req, res){
    socket.on('connection', function(client) {
        req.session.ioid = client.sessionId;
        req.session.channel = req.param('channel');
        req.session.username = req.param('username');
        //I want the code below happen just once                
        res.header('Content-Type', 'text/plain');
        res.header('Access-Control-Allow-Origin', '*');
        res.send({sid:req.session.id});
    });
});

你可以在socket.on的闭包中看到res.header和res.send。这些“res”将一直执行,并导致错误“无法在发送后设置标头”。我正在寻找一种方法使此代码块 -
res.header('Content-Type', 'text/plain');

res.header('Access-Control-Allow-Origin', '*');

res.send({sid:req.session.id});

-发生一次。
2个回答

8
app.get('/', function(req, res){
    socket.on("connection", function(client) {
        req.session.ioid = client.sessionId;
        req.session.channel = req.param('channel');
        req.session.username = req.param('username');
    });

    socket.once('connection', function(client) {
        //I want the code below happen just once                
        res.header('Content-Type', 'text/plain');
        res.header('Access-Control-Allow-Origin', '*');
        res.send({sid:req.session.id});
    });
});

使用.once


2
@maerics 为了满足您的追求精确,我已经将整个东西都包在 get 函数里了。 - Raynos
你能帮我澄清一下相关主题的理解吗?为什么在这个片段中,你要将那些套接字事件监听器绑定在 get / 中呢?据我所知,socket.on 只是添加事件监听器以便监听任何套接字连接,因此整个代码片段看起来像是“在有人尝试获取 '/' 之前不要监听此套接字事件”,但随后它将继续监听其他用户的事件,无论他们尝试获取什么,并且当有人尝试获取 '/' 时,它还会生成更多的事件监听器。看起来我完全误解了什么... - Max Yari

3

尝试将响应头从连接回调函数移到“get /”回调函数中:

app.get('/', function(req, res){
    socket.on('connection', function(client) {
        req.session.ioid = client.sessionId;
        req.session.channel = req.param('channel');
        req.session.username = req.param('username');
    });
    res.header('Content-Type', 'text/plain');
    res.header('Access-Control-Allow-Origin', '*');
    res.send({sid:req.session.id});
});

但是你的示例中顺序似乎有些奇怪。如果每次处理新请求时都向套接字添加连接回调,那么你可能会得到一堆(潜在的)冲突会话属性。你可能需要重新考虑一下。


啊,看起来也许不是我误解了套接字事件监听器的垃圾邮件问题,这是我在回复更高级别评论时谈到的... - Max Yari

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接