Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding promise rejection in node.js

I am trying to understand promises in node.js. Here is a sample code

con.queryReturnPromise("SELECT * FROM bookings WHERE driverId = " + accId + " AND bookingStatus = " + config.get('BOOKING_STATUS_ACTIVE') + " LIMIT 1")
  .catch((err) => {

    callback({
      "message": "Success",
      "error": true,
    });
    console.log("mysql query error");
    return Promise.reject();
  })
  .spread((rows, fields) => {
    if (rows.length != 1) {
      return Promise.reject();
    }
    mBooking = rows[0];
    var query = "INSERT INTO locations SET timeStamp = " + timeStamp + " latitude = " + lat + ", longitude = " + lng + ", bookingId = " + mBooking.id;
    return con.queryReturnPromise(query)
  })
  .catch((err) => {
    if (err)
      console.log("Adding Location error" + err);
    return Promise.reject();
  })
  .spread(() => {
    return funcs.getBooking(con, mBooking.id)
  })
  .then((booking) => {
    if (mBooking.userId.toString() in userSockets) {
      userSockets[mBooking.userId].emit(config.get('EVENT_USER_UPDATE_BOOKING'), {
        "message": "Success",
        "error": false,
        "booking": booking
      });
      userId = mBooking.userId.toString();
    }
    callback({
      "message": "Success",
      "error": false,
      "booking": booking
    });
  })
  .catch((err) => {
    if (err)
      console.log(err);
  });

The code is quite simple. However i have one confusion. If return Promise.reject() is being called, where would the function lead to, Which code will be called. E.g if the first catch clause is called and it calls return Promise.reject() where part of below code will run afterwards

Promises in for loop

data = JSON.parse(data);
            var promisesArray = [];
            for (var i = 0; i < data.length; i++) 
            {
                var location = data[i];
                var lng       = location.lng;
                var lat       = location.lat;
                var bearing   = location.bearing;
                var deltaTime = location.deltaTime;
                var timeStamp = location.timeStamp;

                var query = "INSERT INTO locations SET timeStamp = " + timeStamp + " latitude = " + lat + ", longitude = " + lng + ", bookingId = " + mBooking.id;


                var promise = con.queryReturnPromise(query)                    
                        .then( () => {                            
                        });

                promisesArray[] = promise;
            }

            Promise.all(promisesArray)
            .then(function(results)
            {
                    callback({
                        "error": false,
                    });            
            });
like image 739
Muhammad Umar Avatar asked Sep 28 '16 06:09

Muhammad Umar


1 Answers

Each time you do return Promise.reject(), the next .catch() handler in that chain will get called. It will skip any .then() handlers up until the next .catch() handler.

Returning a reject promise from either a .then() handler or a .catch() handler makes the current promise chain be rejected. So, as more handlers down the chain are encountered, the next reject handler in the chain will get called.

When you hit a .catch() handler, what happens after that .catch() depends upon what the .catch() does. If it throws or returns a rejected promise, then the promise stays in the rejected state and the next .catch() in the chain will execute. If it returns nothing or any regular value (other than a promise that ultimately rejects), then the promise becomes resolved (no longer rejected) and then next .then() handler in the chain runs.

Here's an example:

a().then(function() {
    // makes promise chain assume rejected state
    return Promise.reject();
}).then(function() {
    // this will not get called because promise is in rejected state
}).catch(function() {
    // this will get called
    // returning a reject promise will keep the promise in the reject state
    return Promise.reject();
}).then(function() {
    // this will not get called because promise is in rejected state
}).catch(function() {
    // this will get called
    return 2;
}).then(function(val) {
    // this will get called because prior `.catch()` "handled" the rejection
    // already
    console.log(val);    // logs 2
}).catch(function() {
     // this is not called because promise is in resolved state
});
like image 63
jfriend00 Avatar answered Oct 09 '22 09:10

jfriend00