Promises in ES6 (Part 2)

Sujeet Kumar Jaiswal
Sujeet’s Blog
Published in
4 min readJun 1, 2016

We will try to understand the then and catch methods, which are used to perform some action after the promise is settled. We will also understand the fulfillment value of a promise.

Related articles: Part 1: Basic Introduction and usages |Part 3: Promise Methods| Part 4 : API based on Promises

then(onFulfilled,onRejected) method

This method is use to perform some action when a promise comes in Fulfilled state (resolved or rejected). This method takes two arguments, which are onFulfilled and onRejected callback (second argument is optional). The first callback is invoked when the promise is resolved and the fulfillment value is passed as the first argument of the function. If you do not want to use the onFulfilled callback for some reason, pass null as the first argument. The Second argument which is optional, is invoked when the promise is rejected which the reason/err passed as the first argument of the function.

The value passed can be a any valid JavaScript value like string, number, array or objects.

somePromise.then(function(data){
//Called when it is resolved
//data - whatever passed in resolve
},function(err){
//Called when promise is rejected [Optional]
//err - whatever passed in reject
});

Chaining then() methods

The then() always returns a new promise object, which allows chaining multiple then methods.

//Ignoring onRejected Callback for brevity
somePromise
.then(function(value){ ... })
.then(funciton(value){ ... })

There are few rules on which it is decided what data should be returned from the then method which could be used by the next then method.

  • onFulfilled callback is called and No return statement : New fulfilled Promise is created internally and returned.
  • onFulfilled callback is called and we return a custom Promise : Internally creates and returns a new promise which resolves the custom Promise object.
  • onFulfilled callback is called and we returned a non-promise value : Internally creates and returns a new promise which resolves the return value.
  • onFulfilled callback is null : A callback is created interanally and replaced with the null. This function will internally created and returns a new onFulfilled promise object whose fulfillment value is same as the parent promise.
  • For onRejected callback, all the above four cases are same with the only change that the promise object which are created internally will be creating rejected promise object instead of onFulfilled promise object.
Promises: then method chaining

The catch(onRejected) method

This method is similar to the using the ‘then’ method with first argument as null and handling only the onRejected case. This sounds more semantically correct for such cases.

//when only error handling is required
somePromise.then(null
,function(err){
...
})
somePromise.catch(function(err){
...
})

The catch method always returns a Promise. The rules for returning the Promise is same as that of then method’s onRejected method with only one additional case given below:

  • If the promise object to which catch() is called gets fulfilled, then the catch() method simply returns a new fulfilled promise object and ignores the onRejected callback. The fulfillment value of the new promise object is same as the fulfillment value of the parent Promise.

Fulfillment Value

In Short:

When a value other than another promise is passed in resolve/reject of a promise, the value passed is the fulfillment value.

But when another promise (say promise-B) is passed in a resolve of a promise (say promise -A), the fulfillment value will be whatever the promise -B passed in its reject or resolve. The overall status of the promise will also be decided by the promise-B.

Detailed :

When a promise is resolved or rejected, we pass certain data (string, Array, Object, etc.) which is received as a parameter in the functions passed in then/catch method.

var a = new Promise(function(resolve,reject){
...
resolve('Result');
...
reject('Reason');
})
a.then(function(data){
...
},function(err){
...
})

Resolve represents the successful operation whereas Reject represents the failed operation, but anyway whatever value we pass during resolve/reject we can access them from the first argument of the function passed in ‘then’ method.

What if we resolve by another promise?

In many case you may need to use a promise inside another promise and you would want to resolve/reject the promise based on the inner promise results. For this, we would resolve the promise by passing the inner promise instead of passing the value. This will cause the promise to be resolved or rejected based on the inner promise reject or resolve and the fulfillment value will be the data from the inner promise’s resolve/reject data. Lets use When a promise is passed in a resolve, the fulfillment value will be from the promised passed and the overall status will be based on the promise passed.a sample code to understand this.

var outerPromise = new Promise(function(resolve,reject){
...
var innerPromise = new Promise(function(res,rej){
...
res('inner Resolved');
...
rej('inner Rejected');
});
resolve(innerPromise); //Outer is always resolve
});
//using outerPromiseouterPromise.then(function(data){
console.log(data); //inner Resolved
},function(err){
console.log(err); //inner Rejected
})

In the above snippet, outerPromise will always resolve and returns the innerPromise which may resolve or reject. When we finally use the outerPromise, even though we resolved it, but since we passed another promise in it, it will be resolved/rejected based on the innerPromise. The final value that is passed as the parameter is the callback will be the value returned from the innerPromise and this will be the final fulfillment value.

--

--