链接承诺与当时和捕获

时间:2014-07-07 20:38:43

标签: javascript 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抛出时调用,第二个then在{{1}时调用成功。怎么办?

3 个答案:

答案 0 :(得分:19)

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

答案 1 :(得分:6)

由于您将蓝鸟用于承诺,因此您实际上并不需要在每个函数之后使用catch语句。你可以将所有的经典产品连在一起,然后用一个捕获物关闭整个产品。像这样:

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

假设错误消息告诉您错误是什么,它仍然可以发送错误特定消息,例如未找到会话'或者'用户未找到',但您只需查看错误消息即可查看它为您提供的内容。

注意:我确定您可能有理由在不管是否出现错误的情况下调用下一个,但是如果出现错误,可能会引发一个console.error(错误)。你收到一个错误。或者,您可以使用其他一些错误处理函数,无论它是console.error还是res.send(404),或类似的东西。

答案 2 :(得分:1)

我正在这样使用它:

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