What is the difference between Promises and Observables?
This is a common question when you first get into Angular development. What is an Observable and how are they different from Promises? It is also an excellent question that highlights the difference between simply dealing with asynchrony and turning asynchrony into a powerful tool of reactivity. This in fact is the fundamental difference between promises and observables. One handles individual asynchronous calls the other provides for an entire platform for rich, functional & reactive programming.
Introduction:
A common question when a newbie developer starting learn about angular and shows always a word Observable. He or she confused or curious about what is the difference between Promise and Observable. So let’s talk about promise & observable.
Simply Promise and Observable both work with the asynchronous operation of any applications.
Promise:
Promises work with asynchronous operations. They always return a single value or an error message.
Why Promise:
It may help to put promises into context, before we dive into the differences between a Promise and an Observable. Before promises, we had callbacks as a way to deal with asynchrony. Callbacks had hell; the hell of deep nesting, callback passing and abstractions, high complexity, poor testability, poor maintainability, etc. Promises provide a cleaner mechanism to deal with asynchronous behavior, allowing us to break that asynchrony down into smaller, simpler, more testable, more maintainable units with looser coupling.
In my view, there are four key advantages that the promises have over simple callback handlers.
- Better definition of control flow of asynchronous logic
- More testable
- Better error handling
- Improved readability
Drawbacks:
- User could not cancel a request to the API.
- User could not retry a failed call.
- As our application gets bigger, promises become hard to manage.
Promises allow us to go from this (which is a very mild case with greatest simplicity):
//Before Promises
funcA(input, (err, resultA) => {
err ? console.log(err) : funcB(resultA, (err, resultB) => {
err ? console.log(err) : funcC(resultB, (err, resultC) => {
err ? console.log(err) : funcD(resultC, (err, resultD) => {
err ? console.log(err) : funcE(resultD, (err, resultE) => {
err ? console.log(err) : console.log(resultE);
});
});
});
});
});
//After
funcA(input)
.then(funcB)
.then(funcC)
.then(funcD)
.then(funcE)
.then(resultE => console.log(resultE))
.catch(err => console.log(err));
const getEmployees = () => { // A method to get employee data
let content; // Variable to store the retrieved data
const url = "https://www.example.com/getEmployeeData"; // Mock url where we get data from
return this.http.get(url).subscribe(results => contents = results);
// this.http is the Angular (for this example) HTTP library you injected into your class to make async requests
// It calls the URL and returns an observable
// We subscribe to that observable to get the data
// No request is made until there is a subscription in case of **cold** observables
}
Note: Remember that, promises is that a request initiated from a promise is not canceled.
Observable:
Observables are things that you can observe. It is something that produces values over time. Produce values non-stop (forever).
- It can produce value and die.
- It can produce an error and die.
- It can provide values for a small duration, pause, and again start sending data.
Why Observables?
The most significant need for Observables arises from async operations.
Observables come into the picture with RxJS library, and they introduce reactive programming. Reactive programming is a method of building applications that will react to changes that happen instead of writing applications where we write code to handles those changes (or imperative programming).
To understand how observables work, we need to understand the two communication strategies between producer and consumer of data.
Asynchronous HTTP Request:
const getEmployees = () => { // A method to get employee data
let content; // Variable to store the retrieved data
const url = "https://www.example.com/getEmployeeData"; // Mock url where we get data from
return this.http.get(url).subscribe(results => contents = results);
// this.http is the Angular (for this example) HTTP library you injected into your class to make async requests
// It calls the URL and returns an observable
// We subscribe to that observable to get the data
// No request is made until there is a subscription in case of **cold** observables
}
Conclusions
Promises and Observables have some things in common. Both allow us to deal with the asynchronous nature of JavaScript, but in a better way than the original, inherent, and classic nested callback handler approach.
Promises allow us to handle individual asynchronous events, chain asynchronous calls together and simplify error management.