这个问题已经在这里有一个答案:
- JavaScript的闭包内环路-简单实用的例子 43个回答
我敢肯定,我的问题是基于缺乏Node.js的非同步编程的理解,但在这里不用。
例如:我有我想要抓取的链接列表。 当每个非同步请求返回我想知道它是哪个URL。 不过,大概是因为比赛条件,每个请求设置为在列表中最后一个值的URL返回。
var links = ['http://google.com', 'http://yahoo.com'];
for (link in links) {
var url = links[link];
require('request')(url, function() {
console.log(url);
});
}
预期输出:
http://google.com
http://yahoo.com
实际输出:
http://yahoo.com
http://yahoo.com
所以我的问题可以是:
- 我如何通过URL(按价值计算)的回调函数? 要么
- 是什么使他们按顺序运行链的HTTP请求的正确方法? 要么
- 别的东西我失踪?
PS:对于1.我不希望它检查回调的参数,但回调知道有关变量的“自上而下”的一般方式的解决方案。
您的url
变量没有作用范围是for
循环,如JavaScript只支持全球和功能范围界定。 所以,你需要为你创建一个函数范围request
调用捕捉url
通过使用即时功能在每次循环值:
var links = ['http://google.com', 'http://yahoo.com'];
for (link in links) {
(function(url) {
require('request')(url, function() {
console.log(url);
});
})(links[link]);
}
BTW,嵌入require
在循环的中间是不是好的做法。 这或许应该重新写为:
var request = require('request');
var links = ['http://google.com', 'http://yahoo.com'];
for (link in links) {
(function(url) {
request(url, function() {
console.log(url);
});
})(links[link]);
}
检查这个博客了。 变量可以通过使用.bind()方法被传递。 在你的情况下,它会是这样:
var links = ['http://google.com', 'http://yahoo.com'];
for (link in links) {
var url = links[link];
require('request')(url, function() {
console.log(this.urlAsy);
}.bind({urlAsy:url}));
}
见https://stackoverflow.com/a/11747331/243639对于这个问题的一般性讨论。
我建议像
var links = ['http://google.com', 'http://yahoo.com'];
function createCallback(_url) {
return function() {
console.log(_url);
}
};
for (link in links) {
var url = links[link];
require('request')(url, createCallback(url));
}