tutorial observables ejemplo javascript angular rxjs reactive-programming

javascript - observables - rxjs observable



Cómo ''esperar'' por dos observables en RxJS (5)

Actualización: Oct, 2018

Anteriormente sugerí el uso del método zip . Sin embargo, desde entonces me encontré usando combineLatest en combineLatest lugar. Así que decidí agregar combineLatest .

CombineLatest emite los últimos valores emitidos de los observables. Mientras que zip método zip emite los elementos emitidos en orden de secuencia .

Por ejemplo, si el observable # 1 emite su tercer elemento y el observable # 2 ha emitido su quinto elemento. El resultado utilizando zip método zip será el 3er valor emitido de ambos observables .

En esta situación, el resultado utilizando combineLatest será el y . Lo que se siente más natural.

combineLatest (observables)

De la documentation reactiveX:

Cada vez que cualquier entrada observable emite un valor, calcula una fórmula utilizando los últimos valores de todas las entradas y luego emite la salida de esa fórmula.

// Observables to combine const name$ = this._personService.getName(id); const document$ = this._documentService.getDocument(); combineLatest(name$, document$, (name, document) => ({name, document})) .subscribe(pair => { this.name = pair.name; this.document = pair.document; this.showForm(); })

Observable.zip (observables)

El método Observable.zip se explica en la documentación de reactiveX :

Combina múltiples observables para crear un observable cuyos valores se calculan a partir de los valores, en orden, de cada uno de sus observables de entrada.

// Observables to combine const name$ = this._personService.getName(id); const document$ = this._documentService.getDocument(); Observable .zip(name$, document$, (name: string, document: string) => ({name, document})) .subscribe(pair => { this.name = pair.name; this.document = pair.document; this.showForm(); })

una nota al margen (se aplica a ambos métodos)

El último parámetro, donde hemos proporcionado una función, (name: string, document: string) => ({name, document}) es opcional. Puedes omitirlo, o hacer operaciones más complejas:

Si el último parámetro es una función, esta función se utiliza para calcular el valor creado a partir de los valores de entrada. De lo contrario, se devuelve una matriz de los valores de entrada.

Entonces, si omites la última parte, obtienes una matriz:

// Observables to combine const name$ = this._personService.getName(id); const document$ = this._documentService.getDocument(); Observable .zip(name$, document$) .subscribe(pair => { this.name = pair[''0'']; this.document = pair[''1'']; this.showForm(); })

En mi aplicación tengo algo como:

this._personService.getName(id) .concat(this._documentService.getDocument()) .subscribe((response) => { console.log(response) this.showForm() }); //Output: // [getnameResult] // [getDocumentResult] // I want: // [getnameResult][getDocumentResult]

Luego obtengo dos resultados separados, primero el _personService y luego el _documentService . ¿Cómo puedo esperar los dos resultados antes de llamar a this.showForm() para finalizar y luego manipular los resultados de cada uno?


Eche un vistazo al método ''combineLatest'', podría ser apropiado aquí. http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#static-method-combineLatest

const { Observable } = Rx const name$ = this._personService.getName(id); const document$ = this._documentService.getDocument(); Observable .combineLatest(name$, document$, (name, document) => ({ name, document })) .first() // or not, implementation detail .subscribe(({ name, document }) => { // here we have both name and document this.showForm() })


Para mí esta sample fue la mejor solución.

const source = Observable.interval(500); const example = source.sample(Observable.interval(2000)); const subscribe = example.subscribe(val => console.log(''sample'', val));

Entonces ... solo cuando se emite el segundo (ejemplo): verá el último valor emitido del primero (fuente).

En mi tarea, espero la validación de formularios y otro evento DOM.


Puede usar ''zip'' o ''buffer'' como lo siguiente.

function getName() { return Observable.of(''some name'').delay(100); } function getDocument() { return Observable.of(''some document'').delay(200); } // CASE1 : concurrent requests Observable.zip(getName(), getDocument(), (name, document) => { return `${name}-${document}`; }) .subscribe(value => console.log(`concurrent: ${value}`)); // CASE2 : sequential requests getName().concat(getDocument()) .bufferCount(2) .map(values => `${values[0]}-${values[1]}`) .subscribe(value => console.log(`sequential: ${value}`));


Utilice el método forkJoin() de observables. Compruebe este enlace para referencia

De los docs RXJS

Este operador se utiliza mejor cuando tiene un grupo de observables y solo se preocupa por el valor final emitido de cada uno. Un caso de uso común para esto es si desea emitir varias solicitudes en la carga de la página (o algún otro evento) y solo desea tomar medidas cuando se ha recibido una respuesta para todos. De esta manera, es similar a cómo puedes usar Promise.all

Observable.forkJoin([character, characterHomeworld]).subscribe(results => { // results[0] is our character // results[1] is our character homeworld results[0].homeworld = results[1]; this.loadedCharacter = results[0]; });

Código tomado de: https://coryrylan.com/blog/angular-multiple-http-requests-with-rxjs