2013-06-23 50 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); 
});