2012-02-23 28 views
0

外部のJSONフィードからデータをスクラップしてmongoDBに格納しようとしています。mongoose findoneコールバックスコープ(NodeJS、express)

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が混乱している場合は、別の方法で試してください。我々はその呼び出しの範囲にiを維持する機能を呼び出している。この第二の例では

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

:あなたはまた、のような何かを行うことができます。これは理にかなっているかもしれません。 (拘束力が明確になる以上に混乱する傾向があります)

+0

ありがとうMarshall!それは素晴らしい説明です。私を真っ直ぐにしてくれてありがとう。 2番目は直ちに意味をなさないので、私は束縛のアプローチも釘付けにしばらく時間をかけます。 – Ghan

関連する問題