2012-03-02 12 views
3

ちょうどnode.jsで遊び始めました。過去のJavaScriptの経験はほとんどありますが、サーバー側での経験はほとんどありません。Node.js + Mongoose ...制御フローの問題?

私は下記のコードを持っていますが、私が探している機能はMongooseを使ってコレクションに商品を追加することですが、 '名前'を使って重複が見つかった場合は、製品情報、パッケージ情報などの選択された情報だけで、重複しています。問題はfindOneと最初の実行で重複が見つからないと仮定しています。私はそれを2回実行すると、重複を検出しますが、それまでにはそれは遅すぎます。以前の「保存」が行われた後にのみfindOneを実行する方法がわかりません。

function insertProduct(data) { 
    var product; 
    Product.findOne({ 
     name: data.name 
    }, function(err, doc) { 
     if (err) throw err; 
     if (!doc) { 
      product = new Product({ 
       name: data.name 
       //other product data 
      }); 
      product.packages.push({ 
       //package data 
      }); 
     } 
     else if (doc) { 
      doc.packages.push({ 
       //package data 
      }); 
      product = doc; 
     } 
     product.save(function(err) { 
      if (err) throw err; 
      console.log('Added: ' + product.name); 
     }); 
    }); 
} 

request(url, function(error, response, body) { 
    if (!error && response.statusCode === 200) { 
     jsonResult = JSON.parse(body); 
     jsonResult.result.forEach(insertProduct); 
    } 
}); 

私はこれは私がまだのホールドを取得しようとしていることを、制御フローの問題にする必要があり実現しています。あなたの助けに感謝します!

答えて

1

非ブロックIOの世界へようこそ、とJavaScript closures :)

その周りに簡単な方法は、製品の作成を分離し、製品が正常に作成された後にパッケージをプッシュすることです。

addProduct = function(name, next) { 
    Product.findOne({name: name}, function(err, doc) { 
    if(doc) { 
     next(null, doc); 
    } 
    else { 
     // create new product... 
     var d = new Product({name: name}); 
     next(null, d); 
    } 
    }); 
}); 

// ... snipped 

jsonResult.result.forEach(function(item) { 
    addProduct(item.name, function(err, doc) { 
    if(err == null) { 
     doc.packages.push({ 
     // stuffs 
     }); 
     doc.save(); 
    } 
    }); 
}); 
+0

明らかにもっと論理的な方法ですが、そのトリックを行うようには見えません。 Product.findOneは、アプリケーションを2回目に実行したときにのみ重複を検出します。最初の実行では、空のコレクションから開始して何らかの理由で新しく作成されたドキュメントが表示されないため、重複を見つけることができません。他のアイデア?再度、感謝します! – dnglbr