簡體   English   中英

Express&Nodejs:僅在創建模式后如何調用“ next()”

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM