Как избежать вложенных обещаний с несколькими операциями Mongoose? - PullRequest
1 голос
/ 15 октября 2019

Извините, я знаю, что в NodeJS уже есть сообщения о проблемах с вложенными обещаниями, но я до сих пор не могу понять это.
Я использую Express и Mongoose и хочу найти Object 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!'); });
          })

Заранее спасибо

Ответы [ 2 ]

0 голосов
/ 15 октября 2019

Наряду с асинхронным ожиданием. используйте блок 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);
0 голосов
/ 15 октября 2019

Простой, используйте 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) {...

...