2015-07-19 74 views
1

我正在創建一個簡單的博客,其中包含標籤的帖子。貓鼬添加對象數組

var postSchema = new Schema ({ 
    title: { type: String, required: true }, 
    content: { type: String, required: true }, 
    tags: [{ type: Schema.Types.ObjectId, ref: 'Tag' }] 
}); 

當用戶發佈帖子時,我將標籤作爲標籤名稱數組獲取。如何循環這些標籤並創建它們,並在第一次保存時將它們添加到帖子中?

我已經試過這樣:

var post = Post({ 
    title: data.title, 
    content: data.content 
}); 

data.tags.forEach(function(name) { 
    Tag.findOrCreate({ name: name }, function(err, tag, created) { 
    post.tags.push(tag); 

    post.save(function(err) { 
     if (err) throw err; 

     console.log('Post saved!'); 
    }); 
    }); 
}); 

但是,這迫使我再次保存後每個標籤。有沒有辦法只保存一次?

回答

2

那麼你當然可以調用.save()只有一次,只是將它移動到處理循環後。但當然,因爲所有的來電來訪是「異步」那麼你需要的是更好的控制,所以你知道什麼時候回調到每一個操作完成:

使用async庫作爲一個輔助的位置:

var post = Post({ 
    title: data.title, 
    content: data.content 
}); 

async.eachLimit(data.tags, 5, function(name,callback) { 
    Tag.findOrCreate({ "name": name },function(err,tag) { 
     if (err) callback(err); 
     post.tags.push(tag); 
     callback(); 
    });   
},function(err) { 
    if (err) throw err; // or some handling as all errors come here 
    post.save(function(err,post) { 

    }) 
}); 

因此,async.eachLimit允許在處理的數組元素的每次完成時觸發「回調」。 「限制」部分實際上只確保許多操作同時運行,因此您不會吃掉堆棧或可用連接。

當處理列表中的所有項目並返回回調函數時,將執行最後一個塊,因此當創建或找到所有項目並將相應數據推送到陣列以備保存時。

以同樣的方式,如果在該循環中出現任何「錯誤」,則執行將交給該最終塊,以便在一個位置處理所有錯誤操作。

+1

@ProvocativePanda如果您還有其他問題,請使用[Ask Question](http://stackoverflow.com/questions/ask)鏈接發佈。您剛剛瞭解到需要「流量控制」來尊重異步執行。如果你有更具體的問題要求他們形成併發布他們,並有人會回答。 –