RxJS

"lodash for async"- Ben Lesh

Front-end async data

Eventos del DOM (0 - N)

Mouse events

Keyboard events

Object events

Drag events

Clipboard events

Media events

Front-end async data

Entradas de usuario alternativas ( 0 - N)

Eventos del DOM (0 - N)

Front-end async data

AJAX  ( 1 ) 

Entradas de usuario alternativas ( 0 - N)

Eventos del DOM (0 - N)

Front-end async data

Web Sockets ( 0 - N )

AJAX  ( 1 ) 

Entradas de usuario alternativas ( 0 - N)

Eventos del DOM (0 - N)

Front-end async data

Animaciones (cancelable)

Web Sockets ( 0 - N )

AJAX  ( 1 ) 

Entradas de usuario alternativas ( 0 - N)

Eventos del DOM (0 - N)

JavaScript async approaches

Sembrar

Cultivar

Calentar

Callbacks

function hacerPalomitasMaiz() {
    sembrar("🌰", (cultivo) => {
        cultivar(cultivo, (brote) => {
            recolectar(brote, (mazorca) => {
                calentar(mazorca, (palomitasMaiz) => {
                    comerPalomitas(palomitasMaiz);
                })
            })
        })
    });
}

Callbacks

y...

el desgrane?

el transporte?

function hacerPalomitasMaiz() {
    sembrar("unaSemillita", function (semilla) {
        cultivar(semilla, function (brote) {
            recolectar(brote, function (mazorca) {
                desgranar(mazorca, function (granos) {
                    calentar(mazorca, function (palomitasMaiz) {
                        yOtraCosa(palomitasMaiz, function (x) {
                            yOtraOtraCosa(x, function (y) {
                                yOtraOtraCosa(y, function (z) {
                                    servirPalomitasMaiz(z);
                                })
                            })
                        })
                    })
                })
            })
        })
    });
}

el ...?

function hacerPalomitasMaiz() {
    sembrar("unaSemillita", function (cultivo) {
        cultivar(cultivo, function (brote) {
            recolectar(brote, function () {
                calentar(mazorca, function (palomitasMaiz) {
                    servirPalomitasMaiz(palomitasMaiz);
                })
            })
        })
    });
}

Promises

function hacerPalomitasMaiz() {
    sembrar("🌰").then(cultivar)
                  .then(recolectar)
                  .then(calentar)
                  .then(comerPalomitas);
}

Promises

¿Y ... si quiero parar el proceso?

¿Y ... las demás semillas?

Promises

Promesas:

  • Futuro garantizado
    • Las promesas no son cancelables
  • Inmutables
  • De un único valor ( single value ) 

Eventos del DOM (0 - N)

Entradas de usuario Alternativas (0 - N)

AJAX  ( single )

Web Sockets (0 - N)

Animaciones (cancelable)

Necesitamos un tipo en JavaScript que nos permita manejar múltiples valores

 

Iterable

  • iterable.iterator()  : obtenemos el iterador
  • iterator.next() : obtenemos el elemento siguiente
    • result.value : el valor generador
    • result.done : indica si fue completado
  • errores son lanzados al momento de ejecutar iterator.next() 

Iterable

const iterator = semillas.iterator();

while (true) {

    try {
        var result = iterator.next(); // do it async
    } catch (err) {
        handleError(err);
        break;
    }
    if (result.done) {
        break;
    }

    var semilla = result.value;
    hacerPalomitasMaiz(semilla);
}

los iterables no fueron pensados para operaciones asíncronas

Iterable -> Observable

(iterable turned inside out)

let result = iterator.next();
let value = result.value;
observer.next = (value) => doStuff(value)
try{
    let result = iterator.next();
} catch(err) {
    handleError(value)
}
observer.error = (error) => handleError(value)
let result = iterator.next();
if (result.done){
    handleCompletion(value)
    break;
}
observer.complete= (error) => handleCompletion(value)

Iterable -> Observable

let observer = {
    next(value) { /*handle next value */},
    error(err) { /*handle error */},
    complete() { /*handle completion */}
};


let observable = new Observable(observer => {
    const token = doAsyncStuff((err, value) => {
        if (err) {
            observer.error(err);
        } else {
            observer.next(value);
            observer.complete();
        }
    });

    return () => {
        cancelAsyncThing(token);
    }
});


observable.observer(observer);

 Observable

Observable creation

helpers

  • Observable.of(value,value,value)
  • Observable.from(promise/iterable)
  • Observable.fromEvent(item,eventName)
  • Observable.interval(milliseconds)
  • Observable.timer(milliseconds)
  • Observable.ajax(url)

Observable subscription ( then)

x.then(handlerFn,errorFn)

Promises  

x.subscribe(handlerFn,errorFn, completeFn)

observables 

Error handling (catch)

Promises  

Observables 

x.catch(error => {
    if (error instanceof okError) {
        return Promise.resolve('okay');
    } else {
        throw error;
    }
});
x.catch(error => {
    if (error instanceof okError) {
        return Observable.of('okay');
    } else {
        throw error;
    }
});

Observables can be retried

myObservable.retry(3);

myObservable.retryWhen(errors =>
              errors.delay(3000));

Finally

Promises  

Observables 

x.finally(()=> {
    //done
});
x.finally(()=> {
    //done
});

Operators

observable
    .filter(x => x > 10)
    .map(x => x * 2)
    .subscribe(x => console.log(x));

Sets tienen operadores

iterable
    .filter(x => x > 10)
    .map(x => x * 2)
    .forEach(x => console.log(x));

Observables tienen operadores !!

Los operadores de los observable difieren de los operadores de los iterables en que los primeros aplican la operación por cada elemento mientras que los segundos a la colección completa

Operators

Simple operators

Map

Simple operators

Simple operators

Simple operators

Simple operators

Simple operators

Simple operators

Simple operators

Simple operators

Simple operators

How Operators Works

  • Subscribe es el último operador que podemos utilizar.
  • El resultado de llamar el método Subscribe es una subscripción.
  • Podemos llamar el método unsubscribe de una subscripción para cancelar el stream.

Para recordar:

 Observable

 let observable = Rx.Observable.of("🌰", "🌰", "🌰");

 observable.mergeMap(sembrar)
           .mergeMap(cultivar)
           .mergeMap(recolectar)
           .mergeMap(calentar)
           .subscribe(palomitas => comerPalomitas(palomitas));

 Observable

Entonces...Qué es RxJS

Programación reactiva

Trata eventos como colecciones

Manipula eventos con operadores

Los observables no van a generar valores hasta que nos subscribimos a él.

Podemos ignorar el futuro ( cancelable)

Typeahead 

Typeahead 

Go

RxJS - Spanish

By Felipe Jaramillo Gómez