2013-06-23 39 views
1

这是一个在Node.js crawler上运行的简化代码,它获取所有数据。 但我怎么插入里面的 “回调”:功能VAR的 “我”从周期(VAR I = 0 ...当我加入名称:DATAS [I]。名称它返回一个错误:函数只能看到三个参数

类型错误:无法读取的不确定

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

声明'i'外的for循环。 –

+0

@bfavaretto事实并非如此。循环变量不是TypeError的主要问题,请参阅我的答案以获取详细信息。 –

+0

@jaux该错误是由试图解决[臭名昭着的循环问题](http://stackoverflow.com/questions/1451009/javascript-infamous-loop-problem),所以欺骗链接是有道理的。顺便说一句,很好的答案。 – bfavaretto

回答

4

您无法通过datasi到这样的回调函数。回调函数将被调用的参数取决于调用者,您无法控制它。

你看到“类型错误:无法读取属性未定义‘未定义’”因为你希望你的回调函数有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) 
+0

谢谢!所有这些细微差别和细微差别。你可以给出一个链接来阅读关于这种风格的语法,当函数放置在()后有一些参数。我第一次看到它。 – khex

+0

@Ligamentum它的函数表达式http://stackoverflow.com/questions/1013385/what-is-the-difference-between-a-function-expression-vs-declaration-in-javascrip –

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