【问题标题】:How to avoid nested promises with multiple Mongoose operations?如何避免多个 Mongoose 操作的嵌套承诺?
【发布时间】:2020-02-11 20:47:20
【问题描述】:

很抱歉,我知道已经有一些帖子处理 NodeJS 中的嵌套承诺问题,但我仍然想不出这个。
我正在使用 Express 和 Mongoose,我想找到一个对象 ID,然后保存一个对象,然后更新另一个对象,但我不明白我应该如何做得比这更好,因为这些是依赖的承诺:

        // Get Client object ID from email
        Client.findOne({ email: req.body.clientEmail })
          .exec()
          .then((client) => {
            // Then add Client ID to program and save
            const program = new Program(req.body);
            program.Client = client._id;
            program.save()
              // Finally add the program to the existing coach user
              .then((program) => {
                Coach.updateOne({ _id: req.session.userId }, { $push: { programs: program._id } },
                  function (err, coachUpdated) {
                    if (err) return handleError(err);
                    console.log(coachUpdated);
                  })
              })
              .then(() => { res.send('New program added!'); });
          })

提前致谢

【问题讨论】:

  • 第二个 Promise 不是将 .then 嵌套在另一个 .then 中,而是 return,并在下一个 outer .then 中使用它
  • 了解异步和等待
  • 尝试使用 async/await 代替 Promises,它将帮助您正确获取数据

标签: node.js express mongoose promise nested


【解决方案1】:

与异步/等待一起。使用 try/catch 块。

async function findClientAndUpdateCoach(req, res) {
    try {
        const client = await Client.findOne({ email: req.body.clientEmail }).exec();

        const program = new Program(req.body);
        program.client = client._id;
        const result = await program.save() // Must be asynchronous in nature to prevent blocking..

        Coach.updateOne({ _id: req.session.userId }, { $push: { programs: program._id } },
            function (err, coachUpdated) {
                if (err) return handleError(err);
                console.log(coachUpdated);
                res.send('New program added!');
            });
    }
    catch (err) {
        return handleError(err);
    }

    findClientAndUpdateCoach(req, res);

【讨论】:

    【解决方案2】:

    简单,使用async/await 我会做类似的事情

    const client = await Client.findOne({ email: req.body.clientEmail })
              .exec();
    const program = new Program(req.body);
    program.Client = client._id;
    const {_id} = await program.save();
    //If this is not a promise. you can still use `promisify` from `utils` standard node.js lib to make it a promise
    // and then call it with await. :) 
    Coach.updateOne({ _id: req.session.userId }, { $push: { programs: _id } },
        function (err, coachUpdated) {
          if (err) return handleError(err);
          console.log(coachUpdated);
    })
    //You can choose to place it inside the callback above.
    res.send('New program added!');
    
    

    注意:外包装函数应以async为前缀,如async function (req, res) {...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-04-07
      • 2018-10-15
      • 2019-05-22
      相关资源
      最近更新 更多