Node.js - 内联裸函数调用和命名函数调用之间的区别

时间:2015-02-20 04:38:45

标签: node.js

我正在学习带有learnyounode的node.js。我遇到了JUGGLING ASYNC的问题。问题描述如下:

我对C / C ++ / C#/ python / etc有很多经验...所以我习惯于在某个方面组织我的代码。我在这个练习中遇到了一个问题,我无法合理化。如果下面的代码是使用getHttp作为第一个for循环中的函数调用运行的 - 程序退出时索引上有一个引用错误(关于第27行......在cbk_handleStream中)。我做了一些搜索,并阅读了关闭'关闭'我认为我正在解决。

一两个小时之后 - 我决定使用更多的节点重写#j;'格式化的样式是getHttp2 ...我几乎100%确定这在语法上是等价的 - 但它不会在索引变量上出错。事实上,它完全按照我认为的方式工作"关闭"应该。

我一遍又一遍地看着这个,我无法理解为什么这应该(或为什么会设计)功能不同。命名回调函数确实有效。我甚至尝试使用bind并发现了同样的问题。

任何想法或解释?在此先感谢您的帮助。

干杯!



var concat = require('concat-stream');
var http = require('http');

// Get the list of URLS passed to the cmd line
var urls = process.argv.slice(2);
var data = [];
var count = 0;

for(var i=0; i<urls.length; i++)
    getHttp(i);


function getHttp(index)
{
    http.get(urls[index], cbk_http);
}

function cbk_http(response)
{
    response.setEncoding('utf8');
    response.pipe( concat(cbk_handleStream) );
}

function cbk_handleStream(buffer)
{
    data[index] = buffer;
    count++;

    if( count == urls.length )
        console.log(data.join('\n'));
}



function getHttp2(index)
{
    http.get(urls[index], function (response) {
        response.setEncoding('utf8');
        response.pipe( concat( function (buffer) {
            data[index] = buffer;
            count++;

            if( count == urls.length )
                console.log(data.join('\n'));
        }))
    });

}
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:1)

快速查看 - indexgetHttp2中的参数,用于getHttp2。但是在getHttp中,它是一个局部变量,并且它超出了cbk_handleStream的范围。

更精确的解释:这是您的代码:

function a() {
  console.log(i);
}

function b(i) {
  a();
}

b(1);
// prints: undefined.

这定义了函数a,它查找全局变量i并打印它。 b定义了一个局部变量i,只有b才能看到;因此i中的a未定义。

function b(i) {
  function a() {
    console.log(i);
  }
  a();
}

b(2);
// prints: 2.

另一方面,这段代码是不同的。 i中的b是相同的,是一个局部变量。不同之处在于ab内定义,并关闭b内范围内的所有变量。因此,a将带有i的引用。当您在i内阅读a时,您不再访问全局变量,而是ba关闭的局部变量(因此,闭包)。< / p>

如果您从a外部调用b,只要在b中定义了function b(i) { function a() { console.log(i); } return a; } var c = b(3); c(); // prints: 3. ,这甚至都有效:

def a():
    print(i)
def b(i):
    a()
b(1)
# NameError: global name 'i' is not defined

def b(i):
    def a():
        print(i)
    a()
b(2)
# prints: 2.

def b(i):
    def a():
        print(i)
    return a
c = b(3)
c()
# prints: 3.

事实上,既然你说你说Python,情况就完全一样了:

i

错误的原因在两种情况下都是相同的:第一个示例中没有闭包,而在第二个和第三个示例中有{{1}}的闭包。