Observables with RxJS 

In computing reactive programming is an asynchronous programming paradigm concerned with data streams and propogation of change.

Reactive programming

RxJS

Provide a set of reactive extensions on which we can perform reactive programming

After looking at this diagram, many software developers will say, “We already know this. This is a pub-sub messaging with the implementation of the Observer pattern.” To some extent, this is correct, but there’s more to it:

1. Rx is meant for the asynchronous non-blocking data processing.

2. Rx offers a simple API with dedicated channels for sending data, errors, and the end-of-stream signal.

3. Any Rx library has about a hundred operators that can be applied to the data stream en route. Operators are easily composable.

4. Some of the Rx implementations (e.g. RxJava2) support the backpressure well. This is a scenario when a producer emits data faster than a consumer can handle.

5. You don’t need special messaging servers to use a Rx library. Everything you need is a part of your app.

So how an Observable sends the data to the Observer? An Observer can implement three methods (their names may slightly vary depending on the language you use):

* next() – here’s a new value from the stream
* error() – here’s an error happened in the stream
* complete() – the stream’s over

**Observer has following options**
* subscribe - subscribe to the new values
* unsubscribe -unsubscribe from subscriptions

Observer Design Pattern

Observable maintains a list of its observers and not anyone can listen to the changes in Observables. Observers explicity ask Observables to add them to the observer list.

Two main components
- Observables
- Observers

// Installing RxJS

npm install rxjs-es


// Import and use
import Rx from 'rxjs/Rx';

Rx.Observable.of(1,2,3)

// Import only which you need
// Size sensitive bundling

import { Observable} from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/map';

Observable.of(1,2,3).map(x => x + '!!!'); // etc

RXJS installation

code block

// Implementation with RxJS

const observable = Rx.Observable.from([1,2,3]); // Observable

const observer = observable.subscribe((val) => console.log('Value: ', val)); // Observer

// Output would be

// Value: 1
// Value: 2
// Value: 3

code block

// Implementation with RxJS

var observable = Rx.Observable.create(function (observer) {
  observer.next(1);
  observer.next(2);
  setTimeout(() => {
        observer.next(3);
        observer.complete();
    }, 3000);

  observer.complete();
});
observable.subscribe(
  value => console.log(value), // Received values
  err => {}, // Error thrown
  () => console.log('this is the end') // Marking completion
);

// Logs
// 1
// 2
// 3
// "this is the end"

code block

// Implementation with RxJS
// Emitting an error message

const observable = Rx.Observable.create((observer) => {
  observer.error('something went really wrong...');
});

observable.subscribe(
  value => console.log(value), // will never be called
  err => console.log(err),
  () => console.log('complete') // will never be called
);

// Logs
// "something went really wrong..."

code block

// Implementation with RxJS
// Unsubscribe method
const observable = Rx.Observable.create(observer => {
  const id = setTimeout(() => observer.next('...'), 5000); // emit value after 5s

  return () => { clearTimeout(id); console.log('cleared!'); };
});

const subscription = observable.subscribe(value => console.log(value));

setTimeout(() => subscription.unsubscribe(), 3000); // cancel subscription after 3s

// Logs:
// "cleared!" after 3s

// Never logs "..."

Push over pull natrue

Pull - Observer ask observable for value
Push - Observable pushes the value to all of its observables

Real world usage

Listening key strokes
Mouse pointer position detections
Any real time scenario

Observables vs Promises

 PROMISES  OBSERVABLES
 - Emits a single value
- Not lazy , i.e executes when read
- Cannot be cancelled
- Emits multiple values
- Lazy i.e not executes until subscribed
- Can be cancelled by unsubscribing

Operators

Operators are functions that can transform the stream data between the moments when the Observable sent them and the function subscribe() received them. In other words, we can transform the data en route. Rx libraries have lots of operators.

Handling Back pressure with RxJS

Pausable Buffers

var source = getStockData()
  .pausableBuffered();

source.subscribeOnNext(function (stock) {
  console.log('Stock data: %o', stock);
});

source.pause();

// Resume after five seconds
setTimeout(function () {
  // Drains the buffer and subscribeOnNext is called with the data
  source.resume();
}, 5000);

Handling Back pressure with RxJS

Controlled Observables

var source = getStockData()
  .controlled();

source.subscribeOnNext(function (stock) {
  console.log('Stock data: %o', stock);
});

source.request(2);

// Keep getting more after 5 seconds
setInterval(function () {
  source.request(2);
}, 5000);

Marble Diagrams

A word of caution. Rx libraries allow you to write less code, but the code readability suffer. The person who reads the code needs to know Rx as well.

deck

By Muhammad AbdulMoiz

deck

  • 583