Promises in ES6 -(Part 1)
An introduction to a new Asynchronous Programming pattern. Will also see how is it different / similar to callback pattern and the original event-based pattern.
What’s Promise?
A promise represents a value that may not be available when it is requested but is guaranteed to be available sometime in future. This value returned in future can be a result of either success or error.
The Promise object is used for deferred and asynchronous computations. A Promise represents an operation that hasn’t completed yet, but is expected in the future. — MDN
Don’t we have similar patterns already available?
Yes, we do have the following two patterns.
- Event Pattern.
- Callback Pattern.
These are generally used interchangeably with help of some wrapper code. For example the XMLHttpRequest is implemented on a Event pattern, but jQuery provides this as a callback pattern
AJAX (XMLHttpRequest) Event Pattern
var request = new XMLHttpRequest();
request.open('GET','http://sujeetjaiswal.com/placeholder/data.json')
request.addEventListener('load',function(){...})
request.addEventListener('error',function(){...})
request.send();
AJAX Callback Pattern (jQuery)
//Omitting details of function parameters and bod
$.ajax({
url:'http://.../data.json',
success:function(){...},
error:function(){...}
})
Problems with above pattern:
- Difficult to maintain state of asynchronous operation.
- The code becomes complex and harder to read / maintain when we have multiple level of nested asynchronous operations.
- Difficult to pipe multiple asynchronous requests one after another.
- What if we have multiple asynchronous tasks, and we want to execute a function only once after all tasks are finished.
- What if we have multiple tasks and want to execute a function if any one of the task is finished only once.
These problems can be easily solved using promises. Enough of comparisons, lets understand Promises …
Promises Basics
Syntax (to create):
new Promise( /* executor */ function(resolve, reject) { ... } );
The above syntax is used to create a promise. In general, we would need it only if we creating a library or some helper functions.
Syntax (to use)
//assuming func() returns a promise
var promise = func();
promise.then(function(value){
/*some code handling success*/
},function(err_value){
/*some code handling error*/
})//more compact
func().then( ... );
The above code shows a typical syntax used with promises. ‘.then’ accepts two functions, the first one is called when the promise is fulfilled/resolved (similar to success-callback) and the second one is invoked if the promise is rejected (similar to error-callback).
//using .catch to handle errors
//assuming func() return a promise
func().catch(function(err_value){
/*some stuff here*/
})
The .catch is used when we are interested in handling errors. It is similar to reject-callback of the .then method. I prefer this over using the reject-callback as it has more clear semantic. This can also be used after the .then to catch any errors after the complete operation.(see below the use in sample code.)
Stated of Promises:
- Pending : This is the initial state of the promise. The resolve or rejected callback is yet to be invoked.
- Fulfilled : The operation is successful and the resolve callback will be invoked
- Rejected : The operation is failed. The reject callback will be invoked.
- Settled : The operation is either in Fulfilled or Rejected state.
To understand this, lets dive into some code. The sample code creates a wrapper over the normal XMLHttpRequest’s get method. The function func() returns a promise. The returned promise when the func() is called is used with .then(…).catch(…). The functions passed as argument in .then will be called depending on if it is resolved or rejected, and then will finally .catch is used as a generic error handler.
Planned parts of the series (Upcoming)
- Promises in ES6–(Part 2/4): Fullfillment value, .then and .catch method in detail
- Promised in ES6–(Part 3/4):Promise.resolve, Promise.reject, Promise.all, Promise.race
- Promised in ES6–(Part 4/4): APIs based on Promises.