我正在构建一个事件应用程序,在我的“事件”架构中,我有一组“标签”架构,因此每个事件可以有一个或多个标签。
事件:
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()
}
},
我的问题是,如何在检查完所有标签后才调用“下一个”?是否可以?谢谢
您可以使用Promise.all等待一系列 promise 的履行。
代码未经测试,但应该为您提供 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);
}
我是一名优秀的程序员,十分优秀!