2017-09-09 17 views
1

一連のネストされたコールバックを使用して、findコマンドで既存のエントリをデータベースで最初にチェックする作業コードがあります。エントリが存在する場合は何もしないでください。エントリが存在しない場合は、dbにエントリを挿入します。ノード、mongodb、および約束の問題

このコードはうまく動作しますが、意味のあるエラー処理を提供しない:

var MongoClient = require('mongodb').MongoClient; 
MongoClient.connect("mongodb://localhost/peeps", function(err, db) { 
     if(err) { 
      if(db) db.close(); 
      return next(); 
     } 
     var query = { section: req.body.section, year: req.body.year, semester: req.body.semester }; 
      db.collection("sections").find(query).toArray(function(err, result) { 

      if(result.length >= 1 ) { 
       db.close(); 
       if(callback) callback(); 
      } else { 
       var days = []; 

       for(var i = 1; i < 6; i++) { 

        if(field['starthour' + i] != '') { 
         var oneDay = {}; 
         oneDay.day = field['day' + i]; 
         // more fields being stored here... 
         days.push(oneDay); 

        } 
       } 

       db.collection("sections").insertOne(
        { 
         coursetitle: req.body.course, 
         // more fields being stored here 
         days: days 
        } 
       ) 
       db.close(); 
       if(callback) callback(); 
      } 
     }) 
    }) 

は約束、コールバック地獄とエラー処理のためのはずの修正を入力します。ですから、私が約束している最初の問題(と私は、キーワードMongodb、約束、ノード、および検索とすべての単一のポストを検索し、試している)は、まだ入れ子の約束を避ける方法です。ここで

は、私は約束戦略を実行しようとしたさまざまな方法の一つの方法は次のとおりです。

var MongoClient = require('mongodb').MongoClient; 
    MongoClient.connect("mongodb://localhost/peeps") 
     .then(function(db) { 
      var query = { section: req.body.section, year: req.body.year, semester: req.body.semester }; 
      db.collection("sections").find(query).toArray(function(err, result) { 
       // I am assuming that returns from this callback won't return to the next .then statement... 
       // how to avoid nesting promises? 
       // If a nested promise is necessary, how do I set it up? .find does not seem to return a promise... (I've tried) 
       if(err) return err; // Where does it go? probably not to the catch statement like I want it to :-(
       if(result.length >= 1) 
        return {db: db, preexist: true}; 
       else { 
        return {db: db, preexist: false}; 
       } 
      }) 
     }) 
     .then(function(o){ 
      // o didn't make it here, so db doesn't exist nor preexist, they're undefined 
      console.log(o.db + o.preexist) 
      // do the insert one if necessary 
     })  
     .catch(function(error) { 
      console.log(error.message); 
     }) 

だから本質的には、私の大きな問題は、次のとおりネストを避けるために、どのように?入れ子になっている約束が必要な場合、最も外側の.catchにエラーを返す方法はありますか?コールバックが指定されていない場合、.findは約束を返しますか? .findが約束を返すことができる場合、結果を配列に格納するための正しい構文は何ですか?

ご協力いただければ幸いです。ただ、他のほとんどのDB プロバイダよう

+0

あなたの最初の.thenは、第2に –

+0

2つのオプションが定義されていないoを理由ですノーリターン、(「セクション」) 'db.collectionをラップを持っていません。(クエリ).toArray'コードを見つけます約束のもとで、または文書が正当なものである場合rect、 'toArray'はとにかくPromiseを返しますので、それを使用してください。しかし、.thenチェイン –

答えて

0

MongoDBは、最新のエラーを取得するための方法を提供しています。

MongoDBの場合、db.getLastError()を使用してエラーオブジェクト/ドキュメントを取得します。 Here are the fields you can use from that document.

より抽象的な観点から、約束事を構成する方法は、データモデル自体、アプリケーションのロジック、および安全に実行できるキャッシュの量によって異なります。

お約束のを連鎖を行う方法は、Promise.all方法や、複数の.thenを必要とせずにDB操作のコレクション()ステートメントおよび/または不必要なDB接続を使用して達成することができます。

function updateDatabase (name, token) { 
    return MongoClient.connect(MONGODB_URL) 
    .then((db) => 
      Promise.all([ 
      db.collection('testCollection').update({name}, {$pull: {tokens: {$in: [token]}}}), 
      db.collection('log').insert({name, token}) 
      ]).then(() => db.close(true) 
     ).then(`Invalid token: ${token} has been removed from: ${name}` 
     ).catch((err) => { db.close(true); throw err }); //catch errors 
    ) 
} 

More information in here: from https://stackoverflow.com/a/45845982/1848744

+0

* .then( '無効なトークン:$ {トークン}が$ {name}'から削除されました)* - noの変数を渡すときは、常にネストするレベルがあります。有効ではありません - 壊れませんが、その目的は何と思いますか? –

関連する問題