2016-08-31 4 views
0

私はイベントアプリケーションをビルドしています。 'イベント'スキーマにはタグのスキーマの配列があります。 1つまたは複数のタグ。Express&Nodejs:スキーマを作成した後にのみ 'next()'を呼び出す方法

イベント:

var EventSchema = new Schema({ 
... 
tags: [{ 
type: Schema.Types.ObjectId, 
    ref: 'Tag' 
    }], 
... 
} 

とタグ:

ユーザーは、イベントに関するすべての情報をイベントミドルウェアに/ POSTにJSONを送るイベントを作成したい
var TagSchema = new Schema({ 
    name:{ 
    type: String, 
    require: true 
    }, 
    times:{ 
    type: Number, 
    default: 0 
    } 
}); 

//json sent by client to server 
{tags:[{name:tag1},{name:tag2}] 

2つのイベントが同じ名前を持つことはできないため、特定のmi ddleware私はいくつかのユーザーがすでにタグを作成しているか、実際にタグを保存する必要があるかどうかを確認します。

// add the tags 
    addTags(req, res, next) { 
    var myBody = req.body; 
    if (myBody.tags) { 
     const len = myBody.tags.length 
     if (len > 0) { 
     // we need to search and store a tag if is has not already created 
     for (let i = 0; i < len; i++) { 
      let currentTag = myBody.tags[i] 
      // find the currentTag in the DB 
      Tag.findOne({ 
      name: currentTag.name 
      }, (err, find) =>{ 
      if (err) return next(err) 
      // if we not find it 
      else if (!find) { 
       // create new one 
       let newTag = new Tag({ 
       name: myBody.tags[i].name 
       }) 
       utils.saveModel(newTag, next, (saved) => { 
       // store it back the ref 
       req.Event.tags.push(saved._id) 
       }) 
      } else { 
       // store the ref 
       req.Event.tags.push(find._id) 
      } 
      }) 
     } 
     console.log('tags added!.'); 
     next() 
     } 
    } else { 
     next() 
    } 
    }, 

私の問題は、どのように私はすべてのタグをチェックした後にのみ '次の'を呼び出すことができますか?出来ますか?あなたはおそらくpromisesを使用する必要がありますが、あなたはあなたの現在のアプローチを変更したくない場合は、あなたがそれを呼ばれるコールバックをカウントすることにより、昔ながらの方法で、行うことができますあなたの

+1

は非同期モジュール – Alex

+1

を見て、[約束](http://mongoosejs.com/docs/promises.html) – Matt

+0

は私がしようとしている、あなたは –

答えて

2

Promise.all一連の約束が成就するのを待つ。

コードはテストされていませんが、Promiseソリューションの概要を示す必要があります。

mongoose = require('mongoose'); 
mongoose.Promise = require('bluebird'); 

// Promise to add a new tag 
function addTag(req, currentTag) { 
    let newTag = new Tag({ 
    name: currentTag.name 
    }) 
    return newTag.save() 
    .then((saved) => { 
     // Store it back the ref 
     return req.Event.tags.push(saved._id) 
    }) 
} 

// Promise to find a tag or add it. 
function findTagOrAdd(req, currentTag) { 
    return Tag.findOne({ name: currentTag.name}) 
    .then((find) => { 
     if (find) return req.Event.tags.push(find._id); 
     // Otherwise create new one 
     return addTag(req, currentTag); 
    }) 
} 

// Promise to add all tags. 
function addTags(req, res, next) { 
    var myBody = req.body; 
    if (! myBody.tags) return next(); 
    if (! Array.isArray(myBody.tags)) return next(); 
    if (myBody.tags.length <= 0) return next(); 

    // Promise to find the currentTag in the DB or add it. 
    var promised_tags = []; 
    myBody.tags.forEach((currentTag) => { 
    promised_tags.push(findTagOrAdd(req, currentTag)) 
    } 

    // Wait for all the tags to be found or created. 
    return Promise.all(promised_tags) 
    .then((results) => { 
     console.log('tags added!.', results); 
     return next(); 
    }) 
    .catch(next); 
} 
+0

ありがとう@マット、それは動作します。私はpromised_tagsが保持していることを本当に理解していません。 –

+1

それは約束の配列です。 2つの関数は非同期であるため、何かをする直前に約束オブジェクトを '返す '。 Promise.allは配列内のすべての約束が成就するのを待ちます。 – Matt

1

をありがとう:あなたが使用することができます

function addTags(req, res, next) { 
    var myBody = req.body 

    if (!myBody.tags || !myBody.tags.length) { 
    next() 
    } 

    let errorOccured = false 
    let checkedTags = 0 

    for (let currentTag of myBody.tags) { 
    Tag.findOne({ name: currentTag.name }, (err, find) => { 
     if (errorOccured) { 
     return 
     } 

     if (err) { 
     errorOccured = true 
     return next(err) 
     } 

     checkedTags += 1 

     if (!find) { 
     let newTag = new Tag({ name: currentTag.name }) 

     utils.saveModel(newTag,() => {}, (saved) => { 
      req.Event.tags.push(saved._id) 

      if (checkedTags === myBody.tags.length) { 
      next() 
      } 
     }) 
     } else { 
     req.Event.tags.push(find._id) 

     if (checkedTags === myBody.tags.length) { 
      next() 
     } 
     } 
    }) 
    } 
} 
+0

感謝感謝感謝します約束してコードを書き直したいけど、ちょっと困っています。私のコードの約束のバージョンをあなたに頼んでもらえますか? –

関連する問題