我正在学习带有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;
答案 0 :(得分:1)
快速查看 - index
是getHttp2
中的参数,用于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
是相同的,是一个局部变量。不同之处在于a
在b
内定义,并关闭b
内范围内的所有变量。因此,a
将带有i
的引用。当您在i
内阅读a
时,您不再访问全局变量,而是b
中a
关闭的局部变量(因此,闭包)。< / 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}}的闭包。