Osservabili RxJS: conLatestFrom e zip
Tempo di lettura: 4 minuti

Nelle applicazioni Angular, spesso ci affidiamo a più di una chiamata asincrona per caricare i dati dei componenti. Ciò spesso richiede che si trattenga l’inizializzazione del componente finché non si ricevono tutte le risposte. Un modo per farlo è utilizzare alcuni dei numerosi operatori combinati della libreria RxJS. In questo tutorial, esamineremo conLatestFrom e cerniera lampo.

Leggi: RxJS Observables Primer in angolare.

conLatestFrom in RxJS

Potresti dire che conLatestFrom è la controparte di combinareUltime. Entrambi gli operatori combinano due o più osservabili sorgente ed emettono valori calcolati dagli ultimi valori di ciascuno. Ciò che distingue conLatestFrom a partire dal combinareUltime si legge nella sua firma:

observable.withLatestFrom(other: Observable, project: Function): Observable

Come potete vedere, conLatestFrom agisce su una sorgente osservabile per combinarla con altri flussi per emettere valori calcolati dagli ultimi valori di ciascuno, ma solo quando la sorgente emette. Allora mentre combinareUltime emette un nuovo valore ogni volta che c’è una nuova emissione da qualunque dei flussi in ingresso, conLatestFrom emette un nuovo valore solo se c’è una nuova emissione dal fonte istanza di flusso.

Piace combinareUltime, attende ancora almeno un valore emesso da ogni flusso e può essere completato senza una singola emissione al termine del flusso di origine. Inoltre, non verrà mai completato se il flusso di origine non viene completato e genererà un errore se uno qualsiasi dei flussi interni viene eliminato.

Per capire meglio come conLatestFrom funziona, usiamolo per calcolare l’IMC (indice di massa corporea) da due flussi di valori di peso e altezza, proprio come abbiamo fatto nel combinareUltime demo:

const weight = of(70, 72, 76, 79, 75);
const height = of(1.76, 1.77, 1.78);

const bmi = weight.pipe(
  withLatestFrom(height, (w, h) => {
  console.log('project values: w =', w, ', h=", h);
  return w / (h * h);
}));
bmi.subscribe(res => console.log("BMI is ' + res));

// Output to console is:
project values: w = 70 , h = 1.78
BMI is 22.093170054286073
project values: w = 72 , h = 1.78
BMI is 22.724403484408533
project values: w = 76 , h = 1.78
BMI is 23.98687034465345
project values: w = 79 , h = 1.78
BMI is 24.933720489837143
project values: w = 75 , h = 1.78
BMI is 23.671253629592222

Nell’esempio sopra, il il peso osservabile fornisce il flusso di origine. Come tale, conLatestFrom calcolato il BMI ogni volta che emette un valore. In ogni caso, il valore finale altezza viene utilizzato il valore di 1,78.

Confronta quell’output con ciò che è stato prodotto da combinareUltime:

// Output to console is:
// project values: w = 75, h = 1.76
// BMI is 24.212293388429753
// project values: w = 75, h = 1.77
// BMI is 23.93948099205209
// project values: w = 75, h = 1.78
// BMI is 23.671253629592222

Ha emesso solo tre valori di BMI: una di ciascuna combinazione di emissioni del flusso di input. In questo caso, il numero di valori emessi da combinareUltime è stato determinato dal flusso che ha emesso il minor numero di valori, che è stato altezza.

zip in RxJS

In genere, il nome di un operatore rivela abbastanza sul suo funzionamento da ricordarci cosa fa, una volta che ci si è familiarizzati con esso. In caso di cerniera lampo, abbiamo un operatore che combina i flussi osservabili in un modo che imita il comportamento di una cerniera su un abbigliamento o una borsa. In quanto tale, combina due o più sequenze di flussi come un array di valori la cui lunghezza è uguale al numero di flussi di input forniti, ovvero una coppia nel caso di due flussi di input. Fare quello, cerniera lampo attende che i valori vengano emessi da tutti i flussi di input, quindi li emette come un array.

Vale anche la pena notare che cerniera lampo emetterà un array solo una volta che ha nuovi valori da ciascuna sequenza di origine. Quindi, se uno degli oggetti osservabili di origine emette valori più velocemente degli altri, la velocità di pubblicazione sarà dettata dal flusso più lento.

Cerniera lampo interrompe l’emissione di valori quando uno qualsiasi dei flussi di input viene completato e i nuovi valori corrispondenti vengono emessi da altri flussi. Al contrario, non verrà mai completato se nessuno dei flussi di input viene completato e genererà un errore se uno qualsiasi dei flussi interni viene visualizzato in errore.

Qui è cerniera lampola firma di:

zip(observable_1[, observable_2...observable_n]): Observable

Il codice seguente mostra il cerniera lampo operatore in azione:

import { map } from 'rxjs/operators';
import { of, zip } from 'rxjs';

let age$ = of<number>(30, 29, 44);
let name$ = of<string>('Bob', 'Carol', 'Jim');
let isDev$ = of<boolean>(true, true, false, false);

zip(age$, name$, isDev$)
  .pipe(map(([age, name, isDev]) => ({ age, name, isDev })))
  .subscribe(res => console.log(res));

// outputs
// { age: 30, name: 'Bob', isDev: true }
// { age: 29, name: 'Carol', isDev: true }
// { age: 44, name: 'Jim', isDev: false }

Nello snippet sopra, tre flussi che emettono tutti i valori senza alcun ritardo. Il cerniera lampo l’uscita viene convogliata all’RxJS carta geografica operatore in modo che i parametri di input vengano visualizzati come nome: valore coppie nella funzione di sottoscrizione. Si noti che l’ultimo valore booleano di falso non viene mai emesso perché gli altri due flussi sono stati completati a quel punto.

UN cerniera lampo Esempio con ritardo

Come mostra questo secondo esempio, l’introduzione di un ritardo per le emissioni del flusso non cambia i risultati:

zip(
  age$.pipe(delay(2000)), 
  name$.pipe(delay(1000)),  
  isDev$.pipe(delay(3000))
)
  .pipe(map(([age, name, isDev]) => ({ age, name, isDev })))
  .subscribe(res => console.log(res));
  
// outputs
// { age: 30, name: 'Bob', isDev: true }
// { age: 29, name: 'Carol', isDev: true }
// { age: 44, name: 'Jim', isDev: false }

L’unica differenza è che cerniera lampo non emetterà nulla finché non avrà ricevuto valori da ciascuno dei flussi di input, il che significa che la funzione di sottoscrizione non riceverà un valore fino a quando il isDev$ osservabile emette dopo un ritardo di 3 secondi. Tutti i valori vengono successivamente emessi in rapida successione.

Operatori di combinazione RxJS

In questo tutorial, abbiamo imparato come utilizzare due dei due più potenti operatori di combinazione della libreria RxJS: conLatestFrom e cerniera lampo.

Tutti i frammenti di codice di cui sopra sono inclusi nel demo di stackblitz.com in modo che tu possa giocare con il codice e osservare i risultati.

Source link

Di Simone Serra

Web Designer Freelancer Realizzazione Siti Web Serra Simone Realizzo siti web, portali ed e-commerce con focus specifici sull’usabilità, l’impatto grafico, una facile gestione e soprattutto in grado di produrre conversioni visitatore-cliente. Elaboro siti internet, seguendo gli standard Web garantendo la massima compatibilità con tutti i devices. Sviluppo e-commerce personalizzati, multilingua, geolocalizzati per potervi mettere nelle migliori condizioni di vendita. Posiziono il tuo sito su Google per dare maggiore visibilità alla tua attività sui motori di ricerca con SEO di base o avanzato.