这是一个在Node.js crawler上运行的简化代码,它可以获取所有数据。 但是如何在循环中插入“回调”: var“i”的函数值(var i = 0 ...当我添加 name:datas [i] .name 它会返回错误:
TypeError:无法读取未定义的属性“未定义”
var Crawler = require("crawler").Crawler;
var crawler = new Crawler;
var datas = [
{name: 'John', url: 'john025'},
{name: 'Jim', url: 'jim04567'}
];
function crauler(done) {
for (var i = 0; i < datas.length; i++) {
var link = 'http://somesite.com/' + datas[i].url;
crawler.queue([{
"uri": link,
// inside this func
"callback": function (error, result, $, datas, i) {
var arr = $('.blogpost').map(function (index) {
var str = $(this).attr('href');
var object = {
numb: str,
name: datas[i].name
};
return obj;
}).get().join(',');
done(arr);
} }]) }; };
crauler (function (arr) {
console.log(arr);
});
答案 0 :(得分:4)
您无法将datas
和i
传递给这样的回调函数。调用回调函数的参数取决于调用者,你无法控制它。
您看到“TypeError:无法读取未定义的未定义属性”因为您希望您的回调函数将datas
和i
作为参数;但调用者只会使用前3个参数调用回调 [crawler callback reference],因此datas
和i
为undefined
。
因此,您应该从行中删除datas
和i
:
"callback": function (error, result, $, datas, i) {
由于datas
是在回调函数的外部作用域中定义的,因此回调可以访问datas
而无需任何特殊处理。对于变量i
,它在其他答案中提到有点棘手,所以你需要为它创建一个闭包。
因此,您的回调函数定义应如下所示:
"callback": (function(i) { // create closure for i
return function (error, result, $) { // no more datas and i here
var arr = $('.blogpost').map(function (index) {
var str = $(this).attr('href');
var object = {
numb: str,
name: datas[i].name // access datas as it
};
return obj;
}).get().join(',');
done(arr);
}
})(i)
答案 1 :(得分:2)
您正试图在循环内部i
周围创建一个闭包,这会导致您出现问题。这个答案可以帮到你:
答案 2 :(得分:2)
您需要一个闭包来捕获值,这是解决问题的一种方法。阅读closures。
的Javascript
var Crawler = require("crawler").Crawler;
var crawler = new Crawler;
var datas = [{
name: 'John',
url: 'john025'
}, {
name: 'Jim',
url: 'jim04567'
}];
function queue(link, i) {
crawler.queue([{
"uri": link,
// inside this func
"callback": function (error, result, $, datas, i) {
var arr = $('.blogpost').map(function (index) {
var str = $(this).attr('href');
var object = {
numb: str,
name: datas[i].name
};
return obj;
}).get().join(',');
done(arr);
}
}]);
}
function crauler(done) {
for (var i = 0; i < datas.length; i++) {
var link = 'http://somesite.com/' + datas[i].url;
queue(link, i);
};
crauler(function (arr) {
console.log(arr);
});