Observables - introducción.
Tags: javascript, rxjs
Published: 2019-01-18 15:31:37


Un Observable es una colección "lazy" de valores a la cual puedes "subscribirte" para así poder tener acceso a los valores. Observable es un nuevo sistema "Push" para JavaScript; este produce múltiples valores "pusheando" a los Observer (consumidores).
  
## ¿Qué es un sistema "push"?

> Un sistema push es donde el Producer determina cuándo enviar la información al Consumer. El Consumer no está al tanto de cuándo recibirá la información.

Las Promise son el sistema de Push más común en JavaScript. Una promesa (Producer) entrega un valor resuelto a callbacks registrados (Consumer), pero, al contrario de las funciones, es la Promise la cual se encarga de determinar precisamente cuando el valor es "pusheado" a los callbacks.

Observable es como un Promise; con la diferencia que un Promise solo puede otorgar un solo valor, mientras que Observable puede otorgar múltiples valores.
  
## Anatomía de un Observable

Los Observable son creados usando el constructor o el operador de creación; son subscritos a un Observer, se ejecuta para entregar `next`, `error` y `complete` notificaciones al Observer y su ejecución **puede** ser terminada.

Hay cuatro conceptos cuando tratamos con Observables:

- Creación de Observable
- Subscripción a Observable
- Ejecución del Observable
- Desechando el Observable

## Funcionamiento

Vamos a poner en práctica algunos de estos conceptos. Primero, creamos un Observable por medio del mètodo `create`:

```javascript
const observable = Observable.create((subscriber) => {

})
```

El parámetro que recibe el callback es una instancia de Subscriber, el cual implementa la interface Observer. Por medio de este Subscriber podemos almacenar valores en la cola y también decidir terminar el trabajo:

```javascript
subscriber.next('Un dato')
subscriber.next('Otro dato')
subscriber.next('Último dato')
subscriber.complete()
subscriber.next('Me olvidé de este') // nunca se enviará
```

Una vez que se hace llamado al método `complete` el subscriber no podrá emitir más datos. Bien, ahora tenemos una cola con mensajes, pero, ¿cómo accedemos a ellos? Aquí es donde entra tallar Subscription.

## Subscripciones

Para poder acceder a los datos que tiene un Observable, tenemos que *subscribirnos* a él mediante un `Observer`. Un `Observer` es simplemente una interface cuya definición indica que contiene tres métodos:

- `next`: este método acepta un argumento el cual es el **dato enviado por el Observable**.
- `error`: este método también un argumento el cual es un error. Puede ser una subclase de `Error` o cualquier otro tipo de dato.
- `complete`: este método es ejecutado cuando el Observable notifica que ya no hay más valores que enviar.

Veamos al Observable en acción con un ejemplo:

```javascript
const observer = {
  next: value => console.log('Valor recibido: ', value),
  error: err => console.error('Error encontrado: ', err),
  complete: _ => console.log('Ya no hay más valores por recibir')
}
observable.subscribe(observer)
```

> **Nota:** No es una coincidencia que el callback de `create` sea un subscriber y que un Observable tenga un método `subscribe`. De hecho, cuando un Observer se subscribe a un Observable, el "subscriber" es ejecutado inmediatamente.


Si ejecutamos ese código obtendremos la siguiente salida:

```
// Valor recibido: 'Un dato'
// Valor recibido: 'Otro dato'
// Valor recibido: 'Último dato'
// Ya no hay más valores por recibir
```

### Abortando subscripciones

Las ejecuciones de un Observable pueden ser **infinitas**. Una práctica común que se desea para un Observer es abortar la ejecución cuando ya no necesitemos seguir observando valores. Para este propósito está la clase `Subscription`.

Cuando nos subscribimos a un observable, inmediatamente obtenemos una instancia de la clase `Subscription`, la cual, tiene entre su prototipo, al método `unsubscribe`. De esta manera, podemos detener la ejecución de un Observable.

```javascript
const subscription = observable.subscribe(observer)
// luego de un rato
subscription.unsubscribe()
```
Así ya no liberamos recursos usados por el Observable, optimizando nuestra aplicación 😉.

En las próximas entregas hablaremos de otros tipos de Observables, entre otras cosas.