私は、ノード、エクスプレス、モンゴーを学んでいて、その過程で、JavaScriptです。私は、rssparserを使って物語のリストを取得し、それらをmongooseを使ってmongoデータベースに保存する機能を得ようとしています。配列を反復処理して、マングースに保存するのに問題があります。コールバックの問題?
私はRSSの取り込みを手に入れました。私はその話を繰り返しています。私は問題を抱えています。私は、1)ストーリーがデータベースにまだ存在していないことを確認し、2)そうでなければ保存する。私は、コールバックの処理方法が失われていると思います。ここに私の現在のコードとコメントがあります。
rssparser.parseURL(url, options, function(err,out){
// out.items is an array of the items pulled
var items = out.items;
var story;
for (var i=0; i<items.length; i++){
//create a mongoose story
story = new schemas.Stories({
title: items[i].title,
url: items[i].url,
summary: items[i].summary,
published: items[i].published_at
});
//TODO: for testing - these show up correctly.
//If I pull 10 stories, I get 10 entries from here that match
//So "story" is holding the current story
console.log("items[i] is :" + items[i].title);
console.log("story title is : " + story.title);
// setup query to see if it's already in db
var query = schemas.Stories.findOne({
"title" : story.title,
"url" : story.url
});
//execute the query
query.exec(function(err, row){
if(err) console.log("error-query: " + err);
console.log("row: "+ row);
if(!row) {
// not there, so save
console.log('about to save story.title: ' + story.title);
story.save(function (err){
console.log("error in save: " + err);
});
}
});
}
});
これを実行すると、私が見ることはコンソール出力がたくさんある:
それはすべてのストーリー(多くは省略)を示す開始しています:
items[i] is :TSA Drops Plan to Let Passengers Carry Small Knives on Planes
story title is : TSA Drops Plan to Let Passengers Carry Small Knives on Planes
items[i] is :BUILDING COLLAPSE:1 Reportedly Dead, 13 Pulled From Philly Rubble
story title is : BUILDING COLLAPSE:1 Reportedly Dead, 13 Pulled From Philly Rubble
items[i] is :CONTROVERSIAL PAST: Obama's UN Nominee Once Likened US 'Sins' to Nazis'
story title is : CONTROVERSIAL PAST: Obama's UN Nominee Once Likened US 'Sins' to Nazis'
items[i] is :WRITING OUT WRIGHTS: Bill Gives First Powered Flight Nod to Whitehead
story title is : WRITING OUT WRIGHTS: Bill Gives First Powered Flight Nod to Whitehead
items[i] is :BREAKING NEWS: Rice Named to Top Security Post Despite Libya Fallout
story title is : BREAKING NEWS: Rice Named to Top Security Post Despite Libya Fallout
はその後(多くは省略)のように続けます。
row: null
about to save story.title: Best Ribs in America
row: null
about to save story.title: Best Ribs in America
row: null
about to save story.title: Best Ribs in America
row: null
about to save story.title: Best Ribs in America
row: null
about to save story.title: Best Ribs in America
row: null
about to save story.title: Best Ribs in America
row: { title: 'Best Ribs in America',
url: 'http://www.foxnews.com/leisure/2013/06/05/10-best-ribs-in-america/',
published: 1370463800000,
_id: 51af9f881995d40425000023,
__v: 0 }
「約保存する」タイトル(フィードの最後のストーリー)を繰り返します。最後の行が示すように、一度ストーリー。
console.logの出力には、すべてのストーリータイトルの出力が上に表示され、次にすべてのものが下のquery.exec()コールの内側から表示されます。すべてのヘルプは高く評価され
...
私はクリーナーメソッドを実装し、それは素晴らしい、ありがとう。私の問題はちょうどタイミング問題でしたか?つまり、out.items内のすべての項目が、そのコールバックが実行される前に反復されています(したがって、最後のout.itemに設定されたストーリー)。 – Mike
問題はスコープと関連があり、結果として競合状態になりました。 forループが反復処理されるとき、 'story'への参照が1つだけあり、配列を反復処理するたびにオーバーライドされます。もしexec関数がすぐに実行されていたら、コードはうまくいきましたが、execのコールバックはすべてforループが終了した後に起こるので、変数に割り当てられたストーリーの最後のインスタンスを参照しますストーリー。彼らが関数で "閉じた"とき、彼らはすべて 'story'のインスタンスを持っています。これは非常に一般的な間違いです – arnorhs