【问题标题】:Chaining promises with then and catch用 then 和 catch 链接 promise
【发布时间】:2014-07-07 20:38:43
【问题描述】:

我正在使用 bluebird Promise 库。我想链接承诺并捕获特定的承诺错误。这就是我正在做的事情:

getSession(sessionId)
  .catch(function (err) {
    next(new Error('session not found'));
  })
  .then(function (session) {
    return getUser(session.user_id);
  })
  .catch(function (err) {
    next(new Error('user not found'));
  })
  .then(function (user) {
    req.user = user;
    next();
  });

但如果getSession 抛出错误,则调用两个catch,以及第二个then。我想在第一个catch 停止错误传播,这样第二个catch 仅在getUser 抛出时调用,第二个thengetUser 成功时调用。做什么?

【问题讨论】:

  • 如果出现错误,为什么要调用 next()?有没有像 next() 这样的 abort() 可以使用?
  • 我正在使用快递。 next 调用下一个中间件。如果你给它传递一个参数,那么它会跳到错误中间件。

标签: javascript bluebird


【解决方案1】:

.catch 方法返回的 Promise 仍然会通过回调的结果来解决,它不只是停止链的传播。您要么需要分支链:

var session = getSession(sessionId);
session.catch(function (err) { next(new Error('session not found')); });
var user = session.get("user_id").then(getUser);
user.catch(function (err) { next(new Error('user not found')); })
user.then(function (user) {
    req.user = user;
    next();
});

或者使用第二个回调到then:

getSession(sessionId).then(function(session) {
    getUser(session.user_id).then(function (user) {
        req.user = user;
        next();
    }, function (err) {
        next(new Error('user not found'));
    });
}, function (err) {
    next(new Error('session not found'));
});

或者,更好的方法是通过链传播错误,并仅在最后调用next

getSession(sessionId).catch(function (err) {
    throw new Error('session not found'));
}).then(function(session) {
    return getUser(session.user_id).catch(function (err) {
        throw new Error('user not found'));
    })
}).then(function (user) {
    req.user = user;
    return null;
}).then(next, next);

【讨论】:

    【解决方案2】:

    由于您使用 bluebird 作为 Promise,实际上您不需要在每个函数之后添加一个 catch 语句。您可以将所有的 then 链接在一起,然后用一个按钮将整个事情关闭。像这样的:

    getSession(sessionId)
      .then(function (session) {
        return getUser(session.user_id);
      })
      .then(function (user) {
        req.user = user;
        next();
      })
      .catch(function(error){
        /* potentially some code for generating an error specific message here */
        next(error);
      });
    

    假设错误消息告诉您错误是什么,仍然可以发送特定于错误的消息,例如“未找到会话”或“未找到用户”,但您只需查看错误消息即可查看它给了你什么。

    注意:我相信无论是否有错误,您都可能有理由调用 next,但在遇到错误的情况下抛出 console.error(error) 可能会很有用。或者,您可以使用其他一些错误处理函数,无论是 console.error 还是 res.send(404) 或类似的东西。

    【讨论】:

      【解决方案3】:

      我就是这样使用它的:

      getSession(x)
      .then(function (a) {
          ...
      })
      .then(function (b) {
          if(err){
              throw next(new Error('err msg'))
          }
          ...
      })
      .then(function (c) {
          ...
      })
      .catch(next);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-10-18
        • 2019-01-12
        • 2021-07-05
        • 1970-01-01
        • 2019-04-06
        • 2017-05-24
        • 1970-01-01
        相关资源
        最近更新 更多