Rakia Ben Sassi
Dec 26, 2018 · 6 min read
Photo by Nathan Dumlao on Unsplash

Inspired by a discussion with a colleague of mine who wanted to know if Observable and promise are the same thing, I decided to write this blog to explain the differences between them.

Promises vs. Observable

Both Promises and Observables help us to work with the asynchronous functionalities in JavaScript. Promises are values that will resolve in asynchronous ways like http calls. They handle a single event when an asynchronous operation completes or fails.

Observables are like Promises, except they work with multiple values, they clean up after themselves, they can be cancelled. If the result of a HTTP request or some asynchronous operations isn’t needed anymore, the Subscription of an Observable allows to cancel the subscription, while a Promise will eventually call the success or failed callback even when you don’t need the notification or the result it provides anymore.

An Observable is like a Stream (in many languages) and allows to pass 0, 1, or more events where the callback is called for each event. They deal with a sequence of asynchronous events.

Observables provide the features of Promise and more:

  • they can have multiple values over time: if we keep the subscription to the newsletter open, we will get a new one every once and a while. The sender decides when we get it but we have to wait until it comes.
  • they have multiple pipelines
  • they support aggregate operations like map, filter, forEach, reduce, …
  • we can do some powerful functions like combining different Observables to a new one with zip, merge orconcat.
Use of Observable in an Angular app

Since Observables are used in reactive programming which deals with a “sequence of asynchronous events”, let’s see with this real-life example from Uladzimir Sinkevich what does this mean:

Say, it’s Friday and John wants to spend this evening with his friend Bob, scarfing pizza and watching one of the Star Wars episodes. Let’s outline the options he has.

  1. John finishes his work. Then goes and orders the pizza, waits till it’s done. Then picks up his friend. And finally (with Bob and pizza) makes it home and gets down to the movie. It will be the sync approach and it will be way too long, so that probably John will have wanted to call the thing off by that time.
  2. John orders his pizza online, phones Bob, invites him to come. He heads home, has his pizza delivered and starts watching the movie (and eating the pizza) without waiting for Bob to show up. That is what can happen with the async approach.
  3. John orders pizza, phones Bob, invites him to come, heads home, and gets his pizza delivered. But this time, he waits until Bob comes and only after that he turns the movie on. This is what the reactive approach is about. You wait till all async actions (changes) are completed and then proceed with further actions.

Observable vs. Streams

At this stage and after seeing what we can do with an Observable, my colleague asked the next good question:
“Can we handle an Observable (in frontend) the same way we handle streams in Java since they have similar operators?”

Observable and Streams look pretty similar. They have look alike operators (filter, map, …) but Observable differs from Streams significantly:

  • A Stream is simply a Collection that arrives over time.
  • Observables are like collections… except they arrive over time asynchronously.
  • Stream can only be used once, Observable can be subscribed to many times.
  • Stream is pull-based: the data-consumer decides when it gets data from the data-producer. The producer is unaware of when data will be delivered to the consumer. This only works with synchronous things. To pull a value from a collection, it has to be available now! If we think about synchronous as “pull”… we can think about asynchronous as “push”…
  • Observable is push-based: the data producer (the creator of the newsletter) decides when the consumer (the subscriber to the newletter gets data). Promises are the most common way of push in Javascript. A promise (the producer) delivers a resolved value to registered callbacks (the consumers), but unlike functions, it is the promise which is in charge of determining precisely when that value is pushed to the callbacks.

Every Javascript function uses the pull; the function is a producer of data, and the code that calls the function is consuming it by pulling out a single return value from its call.

An Observable is a producer of multiple values, pushing them to subscribers. We subscribe to an Observable and we will get notified when the next item arrives onNext, or when the stream is completed onCompleted, or when an error occurred onError. Because with Observable we receive onNext, onCompleted, onError events. Other stuff we could do is caching, throttling, ...

Pull with Iterator vs Push with Observable
Iterator vs Observable in Java

Java 8 Streams API vs RxJava

Let’s take the example of Streams from Java 8 Streams API (java.util.stream) and Observables from RxJava (the ReactiveX API for Java, for asynchronous programming with observable streams). Those 2 APIs are not built for the same usage.

  • We can perform asynchonus tasks using RxJava.
  • With Java 8 stream, we will traverse items of your collection.
  • We can do pretty much the same thing in RxJava (traverse items of a collection) but, as RxJava is focussed on concurrent task, …, it use synchronization, latch, … So the same task using RxJava may be slower than with Java 8 stream.
  • RxJava can be compared to CompletableFuture, but that can be able to compute more than just one value.
  • By default RxJava is single threaded. Unless we start using Schedulers, everything will happen on the same thread.
Backend implementation: REST method returning an Observable

One last thing: Streams vs. Collections

As you’ve noticed, there is a fourth player in our story: it’s the Collection. Java 8 Streams API provides a mechanism to work with Java collections. It’s about converting collections to a stream, processing the elements in parallel and then gathering the resulting elements into a collection.

  • A collection is an in-memory data structure which holds elements within it. Each element in the collection is computed before it actually becomes a part of that collection. So, it’s a set of eagerly computed values.
  • Streams are fixed data structures which computes the elements on-demand basis. The Java 8 Streams can be seen as lazily constructed Collections, where the values are computed when user demands for it.
  • Like functional programming languages, streams support aggregate operations which can be executed in series or in parallel: filter, map, reduce, find, match, sort, limit, collect, …
  • Streams also support Pipelining and Internal Iterations: most of java 8 stream operations returns Streams only. This help us creating chain of various stream operations → this is called as pipelining. The pipelined operations looks similar to SQL Query.

That’s it for today!

I hope you enhanced you understanding of promise, observable and stream and that next time you come across those terms they will not bewilder or confuse you.

JavaScript in Plain English

Learn the web's most important programming language.

Rakia Ben Sassi

Written by

A Software Engineer obsessed with continuous learning | I’m writing about software engineering, life, and human development.

JavaScript in Plain English

Learn the web's most important programming language.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade