猫鼬在保存之前等待查找完成

时间:2020-10-07 07:39:47

标签: node.js mongodb mongoose

我正在尝试将一个具有对另一个集合的引用的新文档保存到MongoDB中,以便在保存之前获取我使用find来获取的所有引用。我需要等待查找完成才能继续,但是我无法使它正常工作。我认为这与诺言有关,但我无法弄清楚。如果我没有清楚地说明这一点,我在下面有一个例子。任何帮助将不胜感激!

人员架构

const personSchema = new Schema(
    {
        name: { type: String, required: true },
        fruits: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Fruit' }]
    }
)

水果模式

const fruitSchema = new Schema(
    {
        name: { type: String, unique: true, required: true },
    }
)

添加代码

router.route('/add').post((req, res) => {
   const name = req.body.name;
   let fruits = [];

   Fruit.find({ name: { $in: req.body.fruits }}, (err, foundFruits) => {
       if (err) res.send(err)
       foundFruits.forEach(fruit => {
            fruits.push(fruit._id);
       });
   });

   const newPerson = new Person({ name, fruits });
   newPerson.save()
       .then(() => res.json('Person added')
       .catch(err => res.status(400).json('Error: ' + err));
}

示例: 我想添加一个名为“ Bob”的人,并引用“香蕉”和“苹果”(假定已添加到数据库中),因此我发出了一个POST请求,其正文为...

{
    "name": "Bob",
    "fruits": ["banana", "apple"]
}

添加它之后,当我检查数据库时,该条目就存在了,但是“水果”具有一个空数组,而不是对“香蕉”和“苹果”的引用。

1 个答案:

答案 0 :(得分:0)

问题是来自find方法的回调需要花费一些时间来执行,然后其余代码才能完成运行。您要做的是等待诺言,以便代码按预期执行:

router.route('/add').post(async (req, res) => {
    const name = req.body.name;
    let fruits = [];

    let foundFruits = await Fruit.find({ name: { $in: req.body.fruits }});
    foundFruits.forEach(fruit => {
        fruits.push(fruit._id);
    });
    
    const newPerson = new Person({ name, fruits });
    newPerson.save()
        .then(() => res.json('Person added')
            .catch(err => res.status(400).json('Error: ' + err));
}

由于您只使用了_id个水果,因此可以使用enter image description here更优雅地完成操作:

router.route('/add').post(async (req, res) => {
    const name = req.body.name;

    let fruits = await Fruit.distinct("_id", { name: { $in: req.body.fruits }});
    const newPerson = new Person({ name, fruits });
    newPerson.save()
        .then(() => res.json('Person added')
            .catch(err => res.status(400).json('Error: ' + err));
}