web-dev-qa-db-ja.com

promise内にネストされたキャッチは必要ですか?

約束の範囲内でキャッチブロックの数を減らしたいと思います。ネストされたキャッチを削除した場合、例外は親キャッチにバブリングしますか?

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));

ネストされた2つのキャッチを削除して、一番下のキャッチのみを保持します。これでいい?

26
wayofthefuture

いいえ、ありません。 chainあなたのプロミスに対してコールバックによって作成された内部プロミスをreturnする必要がある場合にのみ、それらは結果プロミスまでバブルアップします。さもなければ、外側の約束はそれらを待つことができず、いつ/どのように解決するか(満たすか拒否するか)わかりません。

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

ロジックの一部を個別の関数に抽出し、return内部プロミスを使用して、プロミスチェーンの例外をバブルアップできます。

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