javascript - Express 和 Nodejs : How to call 'next()' only after have created schemas

标签 javascript node.js

我正在构建一个事件应用程序,在我的“事件”架构中,我有一组“标签”架构,因此每个事件可以有一个或多个标签。

事件:

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);
}

关于javascript - Express 和 Nodejs : How to call 'next()' only after have created schemas,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39245012/

相关文章:

javascript - 在nodejs中使用stringify获取cookie ID

javascript - Node.js mysql 查询未定义

node.js - AWS Lambda NodeJS12.x - 加载共享库时出错 : libXrender. so.1

javascript - 使用 React Native 为数组中的每个对象打印图像

javascript - Knockout.js 计算数组属性

javascript - zapier-platform-cli 初始化错误!埃诺特 : no such file or directory

javascript - socketio 手动设置套接字 ID

javascript - 按顺序订阅所有可观察量,然后在所有完成后将值作为数组发出

javascript - typescript typeof 字符串无法按预期工作

javascript - 是否有可能在 Javascript 的 css3 转换期间获取目标计算的 css 属性值?