web-dev-qa-db-fra.com

Des captures imbriquées dans les limites des promesses sont-elles requises?

Nous aimerions réduire le nombre de blocs de capture dans nos promesses. Si nous supprimons les captures imbriquées, les exceptions bouillonneront-elles jusqu'à la capture parentale?

temporaryUserModel.findOne({email: req.body.email})
    .then(tempUser => {
        if (tempUser) {
            temporaryUserModel.findOneAndUpdate({_id: tempUser.toJSON()._id}, user)
                .then((doc) => {
                    return res.status(200).json({
                        status: 'Success',
                        data: {url: planOpted.chargifySignupUrl}
                    });
                })
                .catch(err => error(err, res));
        } else {
            temporaryUserModel(user).save()
                .then((doc) => {
                    return res.status(200).json({
                        status: 'Success',
                        data: {url: planOpted.chargifySignupUrl}
                    });
                })
                .catch(err => error(err, res));
        }
    })
    .catch(err => error(err, res));

Nous aimerions supprimer les deux captures imbriquées et ne garder que la capture en bas. Est-ce correct?

26
wayofthefuture

Non, ils ne le feront pas. Ils ne bouillonnent jusqu'à la promesse de résultat que si vous chaîne vos promesses, pour lesquelles vous devez return les promesses internes créées par les rappels. Sinon, la promesse extérieure ne peut pas les attendre et ne saura pas quand/comment elles se résolvent (si elles se réalisent ou refusent).

temporaryUserModel.findOne({email: req.body.email}).then(tempUser => {
    if (tempUser) {
        return temporaryUserModel.findOneAndUpdate({_id: tempUser.toJSON()._id}, user);
//      ^^^^^^
    } else {
        return temporaryUserModel(user).save();
//      ^^^^^^
    }
}).then((doc) => {
// no need to duplicate this code when you chain anyway
    return res.status(200).json({
        status: 'Success',
        data: {url: planOpted.chargifySignupUrl}
    });
}).catch(err => error(err, res));
16
Bergi

Vous pouvez extraire une partie de la logique dans des fonctions distinctes, et return l'intérieur promet de faire remonter toutes les exceptions à la chaîne de promesses:

temporaryUserModel.findOne({email: req.body.email})
  .then(updateTempUser)
  .then(formatResponse)
  .catch(err => error(err, res));

function updateTempUser(tempUser) {
  if (tempUser) {
    return temporaryUserModel.findOneAndUpdate({
        _id: tempUser.toJSON()._id
    }, user);
  } else {
    return temporaryUserModel(user).save()
  }
}

function formatResponse(doc) {
  return res.status(200).json({
    status: 'Success',
    data: {url: planOpted.chargifySignupUrl}
  });
}
4
hackerrdave