Tutorials

JavaScript Observables in 5 Minutes

Observables offer a powerful, flexible way to handle asynchronous processes in JavaScript. If you're curious about how they compare to promises, check out our analysis in Observable vs Promise..which is better?

Key Takeaways

  • Observables are not natively part of JavaScript, but the RxJS library provides robust tools to implement them.
  • Observables enable lazy execution, meaning they don't execute until subscribed to.
  • They are especially useful for handling asynchronous data streams and provide more flexibility than promises.
  • With observables, you can subscribe and unsubscribe dynamically, offering more control over async operations.

What are Observables?

Observables are functions that emit values over time. Observers, which consume these values, subscribe to observables. This setup is akin to a publisher-subscriber model, making observables an excellent choice for managing asynchronous programming tasks in frameworks like Angular and libraries like React.

JavaScript itself doesn't include observables, but you can tap into them through the RxJS library, known as "Reactive Extensions for JavaScript." It provides an Observable class and a suite of tools for working with reactive programming concepts.

Rather than relying solely on RxJS, you can build a basic understanding of observables by creating a custom Observable class:

class Observable {
    constructor(subscriber) {
        this._subscriber = subscriber;
    }

    subscribe(observer) {
        return this._subscriber(observer);
    }
}

let myObservable = new Observable(observer => {
    setTimeout(() => {
        observer.next("got data!");
        observer.complete();
    }, 1000);
});

let myObserver = {
    next(data) {
        console.log(data);
    },
    error(err) {
        console.log(err);
    },
    complete() {
        console.log("request complete");
    }
};

myObservable.subscribe(myObserver);
// After 1 second: "got data!"
// "request complete"

This simple example is inspired by Netanel Basal's article on observables and illustrates the core mechanics of an observable implementation.

Deep Dive into Observables

What Makes Observables Special?

Observables provide a sophisticated method for dealing with events, asynchronous tasks, and multiple values in JavaScript—essentially functions that emit values. Observers, defining their own next(), error(), and complete() callbacks, subscribe to these observable functions to "listen" for data emission based on various events.

The Case for Observables

Observables have emerged as a powerful evolution in handling asynchronous activities. While Promises address the issues of nested callbacks, observables represent a step further, adeptly managing backpressure conditions and real-time event streams. Jen Looper's insights in her article on observables for Angular developers express this paradigm shift well.

Reactive Programming at Its Core

Observables embody the core tenets of reactive programming, where asynchronous data streams and change propagation are central. Here, observables represent data streams while observers act as the listeners to these streams.

JavaScript Observables vs Promises

If you're experienced with promises, you might wonder why bother with observables at all. While promises are excellent for single-value asynchronous tasks, observables shine with continuous data streams. Here's why:

Eager vs. Lazy Execution

Promises execute immediately upon creation, representing an ongoing process. In contrast, observables wait—they're lazy. They don't execute until subscribe() is called, conserving resources until necessary.

Cancellable vs. Non-cancellable

Native JavaScript promises aren't cancellable. Observables, however, can be unsubscribed from, providing a mechanism to halt execution and release resources.

Always Async vs. Optional Async

Promises always operate asynchronously. Observables can handle both asynchronous and synchronous operations, such as iterating an array or responding to events.

Multicast vs. Unicast

Promises are multicast—once resolved, every subsequent then-call shares the same result. Observables, by default, are unicast: each observer gets its own independent execution, although strategies like the RxJS share() method can emulate multicast behavior.

Push vs. Pull

Unlike promises, which resolve or reject once, observables can "push" multiple emissions to subscribers by invoking next() repeatedly, facilitating a more dynamic pub-sub interaction over time.

For a more comprehensive comparison, Mateusz Podlasin's article on this topic is a valuable resource.

Conclusion

Observables represent a versatile tool in your JavaScript toolkit for managing complex asynchronous operations. They defer execution until necessary and offer a more nuanced alternative for multi-value async situations compared to traditional promises.

Though not a native JavaScript feature, the widespread adoption of RxJS in frameworks and libraries maintains observables' relevance and utility.

FAQ

Are Observables part of JavaScript's standard library?

No, observables are not part of the standard JavaScript library. They are implemented via libraries like RxJS.

Can observables handle both synchronous and asynchronous operations?

Yes, observables can handle both. While often used for async tasks, they can also process synchronous data, such as array iterations.

Is there any overhead in using observables?

Observables can introduce complexity with their setup and management, especially when combining multiple observables, but they offer greater flexibility for complex async scenarios.

Do I need a special framework to use observables?

No special framework is needed to use observables, but RxJS is a common library that provides comprehensive support for implementing them.

Mastering the tech interviewWhat everyone is doing wrong in tech interviews