简体   繁体   中英

Node.js: How to handle promise-changing in a proper way

I've got a Node.js (express.js)-Server where I'm providing a simple auth-api.

In one of my routes, I'm changing a lot of sub-steps before returning the "resource".

I'm using bluebird for the promises.

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

So I'm wondering...

  1. how I could interrupt the chain when detecting some error in sub-steps (for now im using p.cancel(); )

  2. in some then s of the chain, I'm returning concrete values (like the token), in some other cases I'm returning promises. Seems like bluebird can handle both and won't interrupt the chain (which actually confusing me since I'm returning a number which has no then -method

I would suggest not using cancellable . That is rarely what you want, and certainly isn't in this case. You should instead throw an error:

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

Then you can catch other error types, if there are any.

For your second question, then , catch , etc. always return promises. You pass them a callback, and they operate on what is returned by that callback. If a promise is returned, it resolves with the return value of that promise once the promise has completed, otherwise it immediately resolves with whatever the callback returned.

You can tell this must be the case, because when then returns, it doesn't yet know the return value of the callback you passed it. So it must always return the same thing; in this case, a promise.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM