1

これは、Node.jsクローラーで実行され、すべてのデータを取得する単純化されたコードです。しかし、 "callback": function value of var "i" from cycle for(var i=0...内に挿入するにはどうすればよいですか? name: datas[i].nameを追加すると、エラーが返されます:

TypeError: undefined のプロパティ 'undefined' を読み取れません

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);
});
4

3 に答える 3

4

このようなコールバック関数にdatasandを渡すことはできません。iコールバック関数が呼び出される引数は、呼び出し元次第であり、制御することはできません。

「TypeError: 未定義のプロパティ '未定義' を読み取ることができません」というメッセージが表示されるのは、コールバック関数にとをパラメーターとして持たせたいためです。ただし、呼び出し元は最初の 3 つの引数のみを使用してコールバックを呼び出す[クローラー コールバック リファレンス] ため、とは.datasidatasiundefined

したがって、インラインからdatasandを削除する必要があります。i

"callback": function (error, result, $, datas, i) {

datasはコールバック関数の外側のスコープで定義されているため、コールバックはdatas特別な処理なしでアクセスできます。variable については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)
于 2013-06-23T16:14:02.297 に答える
2

値を取得するにはクロージャが必要です。これは問題を解決する 1 つの方法です。閉鎖について読んでください。

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);
});
于 2013-06-23T15:56:28.800 に答える
2

i問題を引き起こしているループ内でクロージャーを作成しようとしています。この答えはあなたを助けるはずです:

ループ内の JavaScript クロージャー – 簡単な実用例

于 2013-06-23T15:47:32.610 に答える