0

我有以下代码:

var dgram = require("dgram");

var start = 27015;

for(var i = start; i < (start + 100); i++)
{
    var server = dgram.createSocket("udp4");

    server.on("message", function(msg, sender) {
        console.log(server.address().port)
    });

    server.bind(i);
}

为什么它总是输出最后一个端口(27114)?

怎么了?我认为这将有助于识别接收服务器的端口。

谢谢你。

4

3 回答 3

3

使用闭包来捕获server回调:

server.on("message", (function (server) {
    return function (msg, sender) {
        console.log(server.address().port);
    };
})(server));

而且我不确定该on方法是如何工作的,但在正常的 JavaScript 事件处理中,this指的是事件适用的对象。所以你可能会忘记闭包,而只是this.address().port用来指代server事件发生的具体情况。

另一种设置方法是:

server.on("message", getOnHandler(server));

function getOnHandler(s) {
    return function (msg, sender) {
        console.log(s.address().port);
    };
}
于 2013-05-15T20:14:59.837 回答
3

伊恩是在正确的轨道上 - 你需要一个关闭。但是,他的方式会导致服务器取消引用。

for(var i = start; i < (start + 100); i++) {
  (function(port) {
    var server = dgram.createSocket("udp4");

    server.on("message", function(msg, sender) {
     console.log(server.address().port)
    });
    server.bind(port);
  })(i);
 }

这将导致每个server实例在闭包中被隔离,但不会被取消引用。它们将保持存在,而不会因范围问题而被覆盖。

于 2013-05-15T20:17:11.007 回答
1

您已经成为变量提升和词法范围的受害者。

您的代码等效于:

var dgram = require("dgram");
var start = 27015;
var i;
var server;

for(i = start; i < (start + 100); i++)
{
    server = dgram.createSocket("udp4");

    server.on("message", function(msg, sender) {
        console.log(server.address().port)
    });

}

这意味着这server将始终是回调内部对服务器的最后分配(嗯,从技术上讲,它将是server回调执行时指向的任何值 - 除非在绑定期间调用它,但它始终是最后一个)。

您可以按照 Ian 的建议使用闭包,但我怀疑这this也将在回调内部设置为服务器。(或者至少以某种方式访问​​它。您必须检查文档。)

于 2013-05-15T20:13:14.523 回答