Promise vs Observable

Sanjay Mehta
4 min readAug 16, 2021

--

There has been an on-going debate in the world of developers, and that is which is better: JavaScript Promises or RxJS Observables? Each one can bring so much value to different projects. It’s a good idea to have a good understanding of each and how it could benefit a project. But before we start looking at some comparisons, let’s do a quick overview of what each one is.

What is a Promise

A promise is an object that encapsulates the result of an asynchronous operation.

Each promise has state, which can have one of the following values:

  • Pending
  • Fulfilled with a value
  • Rejected for a reason

The just created promise is in a pending state. The promise maintains the pending state as long as the asynchronous operation behind is in progress.

Then, depending on how the asynchronous operation completes, the promise state changes to either:

A) fulfilled (when the async operation completed successfully)

B) or rejected (when then async operation failed).

In JavaScript, you can create a promise object using a special constructor

const promise = new Promise((resolve, reject) => {
// Async operation logic here....
if (asyncOperationSuccess) {
resolve(value); // async operation successful
} else {
reject(error); // async operation error
}
});

What is Observable

Observable are just that — things you wish to observe and take action on. Angular uses the Observer pattern which simply means — Observable objects are registered, and other objects observe (in Angular using the subscribe method) them and take action when the observable object is acted on in some way.

To use observable, Angular uses a third-party library called Reactive Extensions (RxJS).

Let’s take a look how can we use Observable in our Angular application.

import { Observable } from 'rxjs/Observable';// Create simple observable that emits three values 
const myObservable = Observable.of(1, 2, 3);
// Create observer object
const myObserver = {
next: x => console.log('Observer got a next value: ' + x), error: err => console.error('Observer got an error: ' + err), complete: () => console.log('Observer got a complete notification')
};
// Execute with the observer object myObservable.subscribe(myObserver); // Logs:
// Observer got a next value: 1
// Observer got a next value: 2
// Observer got a next value: 3
// Observer got a complete notification

Here are the main differences which is covered in this blog post:

Eager vs Lazy

Promise is eager , hence execute immediately, and just once. The computation of the result is initiated when the promise is created. There is no way to restart work. All then clauses (subscriptions) share the same computation.

const welcomePromise = new Promise(resolve => {  
console.log("In Promise executor fn");

resolve("Welcome!");
});
console.log("Before calling the then method");

welcomePromise.then(console.log);
// console output:
// In Promise executor fn
// Before calling the then method
// Welcome!

Observables is lazy , since not executed until a consumer subscribes. The subscribe() executes the defined behavior once, and it can be called again. Each subscription has its own computation. Resubscription causes recomputation of values.

import { Observable } from "rxjs";const welcomeObservable$ = new Observable(observer => {   console.log("In Observable producer fn");   observer.next("Welcome!"); 
observer.complete();
});
console.log("Before calling the subscribe method"); welcomeObservable$.subscribe(console.log);
// console output:
// Before calling the subscribe method
// In Observable producer fn
// Welcome!

Async vs Sync

Even if immediately resolved, the Promise is always asynchronous.

const welcomePromise = new Promise(resolve => {  
console.log("In Promise executor fn");

resolve("Welcome!");
});
console.log("Before calling the then method");

welcomePromise.then(console.log);
console.log("After calling the then method"); // console output:
// In Promise executor fn
// Before calling the then method
// After calling the then method
// Welcome!

The Observables may be synchronous or asynchronous

Synchronous

import { Observable } from "rxjs";const welcomeObservable = new Observable(observer => {   console.log("In Observable producer fn");observer.next("Welcome!"); 
observer.complete();
});
console.log("Before calling the subscribe method");
welcomeObservable.subscribe(console.log);// console output:
// Before calling the subscribe method
// In Observable producer fn
// Welcome!

Asynchronous

import { Observable } from "rxjs";const asyncObservable = new Observable(observer => {   console.log("In Observable producer fn");setTimeout(() => {observer.next("Async!"); 
observer.complete();
} , 1000)});
console.log("Before calling the subscribe method");
asyncObservable.subscribe(console.log);console.log("After calling the subscribe method");// console output:
// Before calling the subscribe method
// In Observable producer fn
// After calling the subscribe method
// Async!

Single vs Multiple values

Promises are most commonly used to handle HTTP requests. In this model, you make a request and then wait for a single response. You can be sure that there won’t be multiple responses to the same request.

const numberPromise = new Promise((resolve) => { 
resolve(5);
});
numberPromise.then(value => console.log(value));
// will simply print 5

Promise is always resolved with the first value passed to the resolve function and ignores further calls to it:

const numberPromise = new Promise((resolve) => { 
resolve(5);
resolve(10);
});
numberPromise.then(value => console.log(value));
// still prints only 5

Observables allow you to resolve (or, as we say, “emit”) multiple values.

const numberObservable = new Observable((observer) => {    observer.next(5);   
observer.next(10);
});
numberObservable.subscribe(value => console.log(value));
// prints 5 and 10

Cancellation

Observable subscriptions are cancellable. Unsubscribing removes the listener from receiving further values, and notifies the subscriber function to cancel work.

const subscription = observable.subscribe(() => {// observer handles notifications});subscription.unsubscribe();

Promises are not cancellable.

Conclusions

There are many differences between Observable and Promise. But the main differences are :

  • The Observable is lazy whereas the Promise is eager
  • The Promise is always asynchronous, while the Observable can be either asynchronous or synchronous
  • The Promise can emit only a single value, whereas the Observable can emit single or multiple values.
  • The Observable subscriptions are cancellable whereas Promises are not cancellable.

Thank you, for reading this post , hope you liked it please give an applause.

--

--