【问题标题】:Are nested catches within promises required?是否需要在 promise 中嵌套 catch?
【发布时间】:2017-05-11 05:55:49
【问题描述】:

我们希望减少我们的 Promise 中的 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));

我们想移除两个嵌套的 catch 并只保留底部的 catch。这样可以吗?

【问题讨论】:

  • 你还没有说为什么你要移除内扣,但我建议看这里--> bluebirdjs.com/docs/api/catch.html和这里--> bluebirdjs.com/docs/api/promise.all.html跨度>
  • 你需要回报你内心的承诺,然后你可以冒泡你的例外
  • rejected promises,因此.catch() 将在promise 链中冒泡当且仅当您从.then() 处理程序返回内部promise 时,您不是。这是将内部承诺附加到外部链的唯一方式。

标签: javascript mongoose promise bluebird


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    不,他们不会。如果你 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));
    

    【讨论】:

    • 这行得通吗? return temporaryUserModel.findOneAndUpdate({_id: tempUser.toJSON()._id}, user).then(()=>{console.log(1)});意思是……如果我退回它并且“then”在最后,它还会起作用吗?
    • 是的,,then(…) 返回一个承诺,您也可以从回调内部return。但是请注意,如果您只使用console.log,则履行值将变为undefined
    猜你喜欢
    • 2019-09-29
    • 1970-01-01
    • 2017-04-03
    • 2019-02-27
    • 1970-01-01
    • 2015-10-29
    • 1970-01-01
    • 2019-01-25
    相关资源
    最近更新 更多