节点 js 中的闭包未按预期工作

Closure in node js not working as expected

本文关键字:工作 闭包 js 节点      更新时间:2023-09-26

我有这段代码:

var responses = [];
for( var i=0; i < Number(process.argv[2]); i++) {
    responses.push(function () {
        var index = i;
        function bar() {
            console.log(index);
        }
        return bar;
    }());
}
responses.forEach(function(d){
    d();
});

其中闭包是使用临时变量 index 创建的。这将输出 0 1 正如预期的那样,打印我想在闭包中捕获的值。

与 http get 回调类似的代码不起作用。

var http = require("http");
var urls = ["http://yahoo.com","http://google.com"];
for( var i=0; i < urls.length; i++) {
   http.get( urls[i] , function(res) {
        var j = i;
        res.setEncoding('utf-8');
        res.on("data", function(d) {
            console.log(j);
        });
    });
}

此代码输出: 2 2

我错过了什么?

var j = i;将设置i的值,这是第一次响应时数组的长度,这就是您每次登录时都会2的原因。

调用匿名函数作为http.get的第二个参数,该参数将返回内部函数来处理响应,并且还将记住创建响应的环境。传递的参数i的值将存在于内存中以供以后使用。

试试这个:

var http = require("http");
var urls = ["http://yahoo.com", "http://google.com"];
for (var i = 0; i < urls.length; i++) {
  http.get(urls[i], (function(i) {
    return function(res) {
      res.setEncoding('utf-8');
      res.on("data", function(d) {
        console.log(i);
      });
    }
  })(i));
}

javascript(es5) 中没有块作用域。所以你使用的 for 循环不会做这个技巧,而是尝试:

  urls.forEach(function(url, i){
      http.get( url , function(res) {           
        res.setEncoding('utf-8');
        res.on("data", function(d) {
            console.log(i);
        });
    });