链接承诺与当时和捕获

Ale*_*erg 25 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();
  });
Run Code Online (Sandbox Code Playgroud)

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

Ber*_*rgi 22

.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();
});
Run Code Online (Sandbox Code Playgroud)

或使用第二个回调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'));
});
Run Code Online (Sandbox Code Playgroud)

或者,更好的方法是通过链传播错误,并且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);
Run Code Online (Sandbox Code Playgroud)


小智 7

由于你使用bluebird作为promises,你实际上在每个函数之后都不需要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);
  });
Run Code Online (Sandbox Code Playgroud)

假设错误消息告诉您错误是什么,仍然可以发送特定于错误的消息,例如"找不到会话"或"未找到用户",但您只需要查看错误消息以查看它给出的内容您.

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