Mar*_*arc 42 javascript asynchronous web-crawler node.js
我确定我的问题是基于对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);
});
}
Run Code Online (Sandbox Code Playgroud)
预期产量:
http://google.com
http://yahoo.com
Run Code Online (Sandbox Code Playgroud)
实际产量:
http://yahoo.com
http://yahoo.com
Run Code Online (Sandbox Code Playgroud)
所以我的问题是:
PS:对于1.我不想要一个检查回调参数的解决方案,而是一个回调知道变量'从上面'的一般方法.
Joh*_*yHK 49
您的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]);
}
Run Code Online (Sandbox Code Playgroud)
顺便说一句,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]);
}
Run Code Online (Sandbox Code Playgroud)
小智 9
查看此博客.可以使用.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}));
}
Run Code Online (Sandbox Code Playgroud)
有关此问题的一般性讨论,请参阅/sf/answers/822313201/.
我建议像
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));
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
42913 次 |
| 最近记录: |