是否需要在承诺范围内嵌套捕获?

时间:2016-12-26 22:15:56

标签: javascript mongoose promise bluebird

我们希望减少承诺中的catch块数量。如果我们删除嵌套的catch,那么异常会冒泡到父catch吗?

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 个答案:

答案 0 :(得分:13)

不,他们不会。如果您链接您的承诺,它们只会冒充结果承诺,您需要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));

答案 1 :(得分:4)

您可以将一些逻辑提取到单独的函数中,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}
  });
}