Node.js:如何正确处理承诺变更

时间:2015-08-18 16:02:29

标签: node.js express promise bluebird

我有一个Node.js(express.js)-Server,我提供了一个简单的auth-api。

在我的一条路线中,我在返回"资源"之前改变了很多子步骤。

我使用蓝鸟作为承诺。

router.post('/register', function(req, res, next) {

      // ------- 1. check if already existing
      var p = store.checkIfExisting(req, res) //-->mongoose .find(). Returns promise
        .then(function(isExisting) {
          if (isExisting) {
            console.log("try to cancel");
            p.cancel();
          }
          // ------- 2. Facebook validation
          return validateFacebookSignedRequest(req.body.fbsrCookie); //True/False
        })
        .then(function(fbIsValid) {
          // ------- 3. create Users
          return store.saveUser(req, res); // --> mongoose.save(). Returns promise
        })
        .then(function(user) {
          // ------- 4. Token generieren
          return store.generateTokenForFbUID(req, res);
        }).then(function(token) {
          // ------- 5. send back the token
          res.send({
            success: true,
            message: token
          });
        })
        .cancellable()
        .catch(function(err) {
          console.log("canceled");
        });
});

所以我想知道......

  1. 在检测到某些错误时如何中断链 子步骤(现在使用p.cancel();

  2. 在链的某些then中,我会返回具体值(如令牌),在其他情况下我会返回承诺。好像蓝鸟可以处理这两个并且不会打断链(这实际上让我感到困惑,因为我返回了一个没有then的数字 - 方法

1 个答案:

答案 0 :(得分:4)

我建议不要使用cancellable。这很少是你想要的,在这种情况下肯定不是。你应该抛出一个错误:

  var p = store.checkIfExisting(req, res)
    .then(function(isExisting) {
      if (isExisting) {
        throw new NotFoundError(); // Some custom error type
      }
      return validateFacebookSignedRequest(req.body.fbsrCookie);
    })
    // ...more steps...
    .then(function(token) {
      res.send({
        success: true,
        message: token
      });
    })
    .catch(NotFoundError, function(err) {
      // whatever you do when its not found
    });

然后你可以捕获其他错误类型,如果有的话。

对于您的第二个问题,thencatch等始终会返回承诺。你传递回调函数,然后它们对该回调返回的内容进行操作。如果返回了promise,则一旦promise完成,它将以该promise的返回值解析,否则它将立即解析返回的回调。

你可以告诉必须这样,因为当then返回时,它还不知道你传递它的回调的返回值。所以它必须总是返回相同的东西;在这种情况下,一个承诺。