ES6 Promises and RxJS Observables are both used to handle async activity in JavaScript. While an Observable can do everything a Promise can, the reverse is not true...
A Promise is a more elegant way of handling async activity in JavaScript.
Promises are native to ES6 meaning you can use them with vanilla JavaScript (assuming you are using ES6 version or later).
let promise = new Promise((resolve) => { setTimeout(() => { resolve("some value") }, 1000`) })promise.then(value => {
console.log(value)
})
some value
A Promise
works by taking a function with (optionally) two arguments resolve
and reject
. The passed in function executes some async code and either resolves or rejects.
Once the Promise resolves, its then()
method executes a handler function with the emitted value.
This is a very basic example of a Promise. For a more in-depth explanation with examples, check out JavaScript ES6
Observables (in the JavaScript context) are the RxJS implementation of the observer design pattern.
Observables are an alternative to Promises for handling async activity:
const { Observable } = require(‘rxjs’);let observable = new Observable((observer) => {
setTimeout(() => {
observer.next(“some value”)
}, 1000)
})observable.subscribe(value => {
console.log(value)
})
some value
Unlike the Promise, Observables aren’t native to JavaScript. This requires us to import the RxJS library:
const { Observable } = require(‘rxjs’);
While you can implement the observer design pattern yourself, the “Observable” in JavaScript usually refers to the RxJS implementation.
A Promise emits a single value:
let promise = new Promise((resolve) => {
resolve(“a”)
resolve(“b”)
})promise.then(value => console.log(value))
a
An Observable can emit multiple values:
let observable = new Observable((observer) => {
observer.next(“a”)
observer.next(“b”)
})observable.subscribe(value => {
console.log(value)
})
a
b
Once a
Promise resolves, that’s it. You can’t call resolve twice and get different values. Only the first value a is returned by the promise.
An Observable can emit multiple values. Calling next()
executes the handler function each time. Both a
and b
are returned.
A Promise executes the moment it is defined:
let promise = new Promise((resolve) => {
console.log(“promise is running”)
resolve(“a”)
})console.log(“start”)
promise.then(value => console.log(value))
console.log(“end”)
promise is running
start
end
a
An Observable executes only when subscribe()
is called:
let observable = new Observable((observer) => {
console.log(“observable is running”)
observer.next(“a”)
})console.log(“start”)
observable.subscribe(value => console.log(value))
console.log(“end”)
start
observable is running
a
end
A Promise executes the moment it’s defined. Even if we don’t call then()
, the Promise executes. This is considered eager execution.
An Observable executes only when subscribe()
is called. If we don’t call subscribe()
, nothing executes. This is considered lazy execution.
A Promise can’t be canceled. That’s it. No example needed.
An Observable can be canceled via unsubscribe()
:
let observable = new Observable((observer) => {
setTimeout(() => {
console.log(“calling next”)
observer.next(“a”)
}, 1000)
})sub = observable.subscribe(value => console.log(value))
sub.unsubscribe()
calling next
Notice how we use setTimeout()
to mimic async activity. By calling unsubscribe()
on our subscription, you can effectively cancel an Observable before it executes.
A Promise is unicast meaning you get the same value every time you call the async flow:
let promise = new Promise((resolve) => {
resolve(Math.random())
})promise.then(value => console.log(value))
promise.then(value => console.log(value))
0.768598539600432
An Observable is multicast meaning a separate execution occurs for every call to subscribe:
let observable = new Observable((observer) => {
observer.next(Math.random())
})observable.subscribe(value => console.log(value))
observable.subscribe(value => console.log(value))
0.6964325798899575
0.5931491554914805
With a Promise we get the same value no matter how many times we call then()
.
With an Observable we get a different value every time we call subscribe()
.
A Promise has async handlers. This means a Promise won’t execute synchronously with the rest of your code:
let promise = new Promise((resolve) => {
resolve(“promise is resolving”)
})console.log(“START”)
promise.then(value => console.log(value))
console.log(“END”)
START
END
promise is resolving
An Observable has sync handlers. This means an Observable WILL execute synchronously with the rest of the code:
let observable = new Observable((observer) => {
observer.next(“next being called”)
})console.log(“START”)
observable.subscribe(value => console.log(value))
console.log(“END”)
START
next being called
END
Notice how the Promise executes asynchronously from the rest of the code. The code doesn’t wait for the Promise to run.
The Observable executes synchronously with the rest of the code. The code waits for the Observable to emit a value before continuing.
Remember that the Observable class is from the RxJs library. The RxJS library is the JavaScript implementation of ReactiveX.
ReactiveX is a project for implementing reactive programming across different languages. You can implement Observables in other languages like Java and Ruby as well.
The ReactiveX API also comes with a bunch of operators which are functions that can be applied to observables. Using RxJS, you can apply functions like map()
and filter()
to values emitted by observables.
The ES6 Promise doesn’t have anything comparable to these operator functions…
Promises and Observables both handle async activity in JavaScript. While the Promise is native to ES6, the RxJS Observable requires the RxJS library.
Observables can do things promises can’t. With observables, you get some extra advantages that can be worth while depending on your use case.
Thanks for reading ❤
If you liked this post, please do share/like it with all of your programming buddies!
Follow us on Facebook | Twitter
☞ The Complete JavaScript Course 2019: Build Real Projects!
☞ JavaScript Programming Tutorial - Full JavaScript Course for Beginners
☞ ES6 Arrow Functions Cheatsheet
☞ Getting Started with ES6 Arrow Functions in JavaScript
☞ The Complete Guide to ES6 Destructuring
☞ Dropbox API / JavaScript ES6 Tutorial - Expense Organizer
☞ Authenticate a Node ES6 API with JSON Web Tokens
#javascript #es6