2012-02-23 52 views
0

我試圖從外部JSON提要中抓取數據並將其存儲在我的mongoDB中。mongoose findone回調範圍(NodeJS,快速)

request(url, function (error, response, body) { 
    if (!error && response.statusCode == 200) { 
     var jsonObj = JSON.parse(body); 
     // console.log(jsonObj.events[1].id) <-- this works 
     for (var i = 0; i < jsonObj.events.length; i++) { 
      // add jsonObj.events[i] as a new record to table 
      // console.log(jsonObj.events[i].id) <-- this works 
      Wnet.findOne({ id : jsonObj.events[i].id }, function (err, doc){ 
       if (err || doc == null) { 
        // console.log(jsonObj.events[i].id) <-- this doesn't work! 
        // record is new, add it 
       } 
      }); 
     } 
    } 
}); 

通知的console.log語句...最後一個(內.findOne的回調)不起作用。

我仍然在學習JavaScript的來龍去脈,但我認爲這是一個範圍問題......回調函數不知道jsonObj。但是,我不知道如何將它傳遞給函數。

退一步,我試圖檢查收集的存在的記錄。如果找不到它,我想從抓取的JSON數組中添加記錄。如果有更好的方法來做到這一點,我很樂意幫助你找到它。

回答

2

這不是範圍問題。就範圍而言,它會通過冒泡尋找變量。所以在findOne它有變量jsonObj。它會冒泡到上面的var jsonObj = ...

我相信你的問題是,你正在循環通過jsonObj.events和發射每個findOne。然後,您正嘗試在各自的findOne回調中調用jsonObj.events[i].id。問題是您的i每次都會增加。當i >= jsonObj.events.length實際結束。所以如果長度是9,那麼當循環退出時,i將最終爲10。所以你的日誌記錄將不起作用。 編輯:爲了澄清,日誌記錄將不會工作,因爲在循環內所有findOne將火災,但回調不會馬上發生。因爲回調是異步的。因此,在回調發生的時候,循環很可能會結束,並且會嘗試記錄不存在的events

試試這個:

request(url, function (error, response, body) { 
    if (!error && response.statusCode == 200) { 
     var jsonObj = JSON.parse(body); 
     //console.log(jsonObj.events[1].id) <-- this works 
     for (var i = 0; i < jsonObj.events.length; i++) { 
      // add jsonObj.events[i] as a new record to table 
      //console.log(jsonObj.events[i].id) <-- this works 
      Wnet.findOne({ id : jsonObj.events[i].id }, function (err, doc){ 
       if (err || doc == null) { 
        console.log(jsonObj.events[this].id); 
        //record is new, add it 
       } 
      }.bind(i)); 
     } 
    } 
}); 

這只是一個處理它的方式。如果bind令人困惑,那麼嘗試一下不同的方法。你也可以這樣做:

request(url, function (error, response, body) { 
    if (!error && response.statusCode == 200) { 
     var jsonObj = JSON.parse(body); 
     //console.log(jsonObj.events[1].id) <-- this works 
     for (var i = 0; i < jsonObj.events.length; i++) { 
      // add jsonObj.events[i] as a new record to table 
      //console.log(jsonObj.events[i].id) <-- this works 
      doFindOne(jsonObj.events, i); 
     } 
    } 
}); 


function doFindOne(events, i) { 
    Wnet.findOne({ id : events[i].id }, function (err, doc){ 
     if (err || doc == null) { 
      console.log(events[i].id); 
      //record is new, add it 
     } 
    }); 
} 

在第二個例子,我們呼籲將保持i在範圍上該呼叫的功能。這可能更有意義。 (綁定往往混淆不清)

+0

謝謝馬歇爾!這是一個很好的解釋,謝謝你讓我挺直。第二個是有道理的,我也需要一些時間來指導綁定方法。 – Ghan 2012-02-24 00:14:30