Promises vs Observables

Promises vs Observables

by Bidisha Das

Promises and Observables are topics that confuse developers a lot. Honestly, as a front-end developer, it is important that we understand the difference between these two. As a matter of fact, Promises and Observable seem to function similarly. Both of them help us perform asynchronous functions in JavaScript. How do we know the difference, then? Before diving into the difference, let us see what they are. Here we are, to learn Promises vs Observables.

Promises

Promises can be considered as a placeholder for future value. A promise is nothing but an abstraction of API. It helps you achieve asynchronous functions synchronously. Sounds confusing? Let us dive deeper. Let us consider you are fetching some data in your application from the backend server. Based on the result of your data, something needs to happen in your application.

Now, what if this fetching takes time? Are you going to wait for the backend server to response and tilll then your app will be at a standstill? Of course not. So, you have to keep your application perform other tasks while your server responds. How do you do that? Promise is your answer.

Let us see , how to declare a Promise.

let promise = new Promise((resolve, reject)=> {
    setTimeout(()=>{
        resolve('Resolved');
        reject('Promise failed.')
    }, 1000);
})
promise.then((result)=>{
    console.log(result);
})
.catch((error)=>{
    console.log(error);
})


What does the above code say?



The Promise callback takes 2 parameters – resolve and reject. We must notice, resolve is called when the callback is successful otherwise reject is called. Inside the instance of promise, we provide an asynchronous function. In this case, it is just a setTimeOut( ) method. After 1 second, the promise will either be successful or it will fail. Hence, inside the setTimeOut( ) method we see that the resolve method is called with a parameter and so is the reject method. The resolve & reject method takes the parameter that is to be returned.

In the end, we call the then( ) method of the promise will a function as a parameter. This function will be returned when the promise is resolved. In this case, after 1 second, on the console, you will see ‘Resolved’, which is the message when the promise is resolved. The catch( ) method similarly will take a function as a parameter, which is returned in case the promise is rejected, or in other words, has errors.

States of Promise

Let us see the various states of Promises. A promise has 3 states , namely:

  • pending: In this state, the promise is still in execution, hence it’s neither fulfilled nor rejected.
  • fulfilled: Here, the operation inside the promise has successfully executed.
  • rejected: In this state, Here, the operation inside the promise has not been successful.

Observable

Observables are nothing but functions that return a stream of values. The object that subscribes to these values is called observers. Hence, Observables returns values to the observers. An important thing to note here is Observables can handle synchronous as well as asynchronous methods. Let us see how to declare an observable. (In JavaScript and Typescript, we need to rely on the ‘rxjs’ library to use observables. )

import {Observable} from 'rxjs';

const observable = new Observable(observer => {
  setTimeout(() => {
    observer.next('From an observable');
  }, 1000);
});

observable.subscribe(result=> console.log(result));


What we have done here can be summarized as follows:

  • We have imported Observable from the rxjs library (https://rxjs-dev.firebaseapp.com/guide/overview),
  • Next, we have instantiated this observable using the new keyword,
  • Next, a function is provided where the asynchronous task is handled and where the observer.next( ) method is called.

In fact, the observer.next( ) is similar to the promise.resolve( ). This method triggers the value to the observer. In the end, just like we use, promise.then( ), we have used observable.subscribe( ). This subscribe( ) method will trigger the subscription to the observable. However, this does not clear the differences between observables and promises. Let us explore more then.

Observable vs Promises

The Lazy Kid vs The Eager Entrepreneur

Observables are lazy, while Promises are Eager

The statement seems confusing. Let me clear this. Observables are executed only when the .subscribe( ) method is called. Where are Promises are executed immediately. Let us see this via an example.

import {Observable} from 'rxjs';

const observable = new Observable(observer => {
  setTimeout(() => {
    observer.next('From an observable');
  }, 1000);
});

console.log('Before Subscribe');
observable.subscribe(result=> console.log(result));


The result will be that you will see ‘Before Subscribe’ being printed before the ‘From an Observable’. This is because the observable will only execute after the subscribe method has been called by the observer. On the other hand, look at this code:

const promise = new Promise(resolve => {
  console.log("Promise executed");
  resolve("Resolved!");
});
console.log("Before calling the promise.then method");
promise.then(console.log);


The result of this is:

“Promise executed” 
“Before calling the promise.then method” 
“Resolved!” 

As you can see, the promise is first executed, then the message is console logged and finally, the promise is now resolved when promise.then( ) is called.

Single Vs Multiple Values

Observables can emit multiple values while Promises can emit only single value. The parameter within the first resolve function is emitted. Let us see this with the help of an example.

const value = new Promise(resolve => {
  resolve("Value1");
  resolve("Value2");
});

value.then(console.log);

The output will be just ‘Value 1’ because only the first resolve method’s parameter is printed. On the other hand, let us look at the observable:

import { Observable } from "rxjs";

const value$ = new Observable(observer => {
  observer.next("Value1");
  observer.next("Value2");
});

value$.subscribe(console.log);

The output will be both ‘Value1’ and ‘Value2’, which clearly indicates both the parameters for the consecutive observer.next( ) methods are being printed.

Unsubscribable

Observables can be unsubscribed whereas promises cannot be unsubscribed, per se. In fact, we can use the observer.unsubscribe( ) method whenever we do not need an observable. As a matter of fact, in frameworks like Angular, React this is particularly useful.

import { Observable } from "rxjs";

const value$ = new Observable(observer => {
  observer.next("Value1");
  observer.next("Value2");
});

value$.subscribe(console.log);
value$.unsubscribe();

As soon as the unsubscribe method is called the observable is destroyed and, consequently, the memory allocated for it is freed. However, promises do not support this feature. Certainly, this poses a disadvantage of promises over observables.

World of Operators

Ever heard the concept of reactive programming? It is a pretty popular programming pattern for budding front-end developers nowadays. Reactive programming is that pattern of programming that comes into play when we want to combine or utilize one or more streams. Streams are emitted by observables and are nothing but collections of data that might not be available all at once.

The biggest disadvantage of a Promise is that it does not support Rxjs Operators. Rxjs operators are used to performing reactive programming. Let us take a small look at what this is like using a method called a filter( )

import { Observable } from "rxjs";

const value$ = new Observable(observer => {
  observer.next("Value1");
  observer.next("Value2");
  observer.next("Value3");
});

value$.filter( result => 
result === 'Value1')
.subscribe((result)=>{
    console.log(result);
});

So as we can see, here we are filtering the value whose string matches with ‘Value1’ using the filter( ) method. As a consequence, we can clearly say to perform such functions and even more complicated ones, observables are our choice. However, such functionality obtained from rxjs operators is not supported by Promises.

That is all for today. I hope you had a good time learning. Thank you! 🙂

Related Posts

Leave a Comment