[英]how to work with 2 schemas, how to save correctly Mongoose, nodejs, express
[英]Express & Nodejs : How to call 'next()' only after have created schemas
我正在構建一個事件應用,在我的“事件”模式中,我有一個“標簽”模式的數組,因此每個事件可以有一個或多個標簽。
事件:
var EventSchema = new Schema({
...
tags: [{
type: Schema.Types.ObjectId,
ref: 'Tag'
}],
...
}
和標簽:
var TagSchema = new Schema({
name:{
type: String,
require: true
},
times:{
type: Number,
default: 0
}
});
當用戶想要創建事件時,它將向事件中間件中的/ POST發送json以及有關該事件的所有信息以及由
//json sent by client to server
{tags:[{name:tag1},{name:tag2}]
由於兩個事件不能使用相同的名稱,因此在特定的中間件中,我檢查是否某些用戶已經創建了標簽,或者我們實際上需要存儲一個。
// 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()
}
},
我的問題是,僅在檢查完所有標簽后才能如何調用“ next”? 可能嗎? 謝謝
您可以使用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);
}
您可能應該使用Promise ,但是如果您不想更改當前的方法,則可以通過計數被稱為回調的舊方法來實現:
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()
}
}
})
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.