函数只能看到三个参数

时间:2013-06-23 15:41:45

标签: javascript node.js

这是一个在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);
});

3 个答案:

答案 0 :(得分:4)

您无法将datasi传递给这样的回调函数。调用回调函数的参数取决于调用者,你无法控制它。

您看到“TypeError:无法读取未定义的未定义属性”因为希望您的回调函数将datasi作为参数;但调用者只会使用前3个参数调用回调 [crawler callback reference],因此datasiundefined

因此,您应该从行中删除datasi

"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周围创建一个闭包,这会导致您出现问题。这个答案可以帮到你:

JavaScript closure inside loops – simple practical example

答案 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);
});