Una delle prime sfide che dovrai affrontare quando lavori con RxJS Observables è farli eseguire in un ordine specifico. A prima vista, questo sembra un obiettivo semplice, ma, quando si tratta di processi asincroni, nulla è mai semplice. Anche se gli osservabili vengono eseguiti in successione, non emetteranno necessariamente valori nello stesso ordine. Quindi, “ordine” può essere applicato sia all’invocazione che alla sottoscrizione.

Per complicare ulteriormente le cose, di solito vorrai passare i valori emessi all’osservabile successivo nella catena e agli abbonati. State tranquilli, RxJS fornisce l’operatore perfetto per ogni occasione; la domanda è quale utilizzare per il compito da svolgere. Si spera che il blog di oggi demistifichi alcuni compiti per la scelta dell’operatore giusto per concatenare gli osservabili.

Prima di iniziare, se hai bisogno di un aggiornamento su JavaScript Observables o ti sei perso il nostro primo articolo di questa serie, dai un’occhiata al nostro Primer RxJS Observables.

Osservabili JavaScript e concat

A volte, vogliamo che due o più osservabili si completino in successione. Per questo, c’è concatena. Tratta i tuoi oggetti osservabili come una fila alla cassa al negozio di alimentari locale; la persona successiva (abbonamento) in fila non può pagare la spesa fino a quando il cliente precedente non ha finito di pagare (completa)!

Ecco uno snippet di codice JavaScript che visualizza diversi messaggi in successione. Il concatena L’operatore assicura che i messaggi vengano visualizzati in ordine, indipendentemente dal tempo necessario per completare ogni osservabile:

// helper method
const delayedMessage = (message: string, delayedTime: number) => 
  EMPTY.pipe(startWith(message), delay(delayedTime));

const concatMessage="Concat message ";
concat(
  delayedMessage(concatMessage + 1, 1000),
  delayedMessage(concatMessage + 2, 3000),
  delayedMessage(concatMessage + 3, 2000),
  delayedMessage(concatMessage + 4, 1000),
  delayedMessage(concatMessage + 5, 4000),
  // clear the screen
  delayedMessage('', 2000)
)
.subscribe((message: any) => userMessage.innerHTML = message);

Nota che, poiché concatena attende il completamento delle osservabili prima di passare a quella successiva, se una di esse non viene completata, le osservabili successive non verranno eseguite!

Raccolta di osservabili con concatAll

In situazioni in cui si dispone di un’origine osservabile che produce altri flussi (osservabili) anziché una raccolta di flussi, è possibile utilizzare concatAll per combinarli ed emettere in sequenza tutti i valori da ogni dato flusso di input. Proprio come concatena, una volta completato il flusso attivo corrente, concatAll sottoscrive l’osservabile successivo nella sequenza. Quando vengono prodotti valori da qualsiasi sequenza combinata, tali valori vengono emessi come parte della sequenza risultante. Questo processo è spesso indicato come appiattimento.

Nel codice seguente, il di e carta geografica gli operatori sono combinati per produrre un numero di osservabili ritardati. dar loro da mangiare concatAll quindi unisce tutti i valori emessi e li trasmette agli abbonati nell’ordine in cui vengono eseguiti:

const randomDelay = (min: number, max: number) =>
  Math.floor( Math.random() * max ) + min;
const msg = 'ConcatAll message ';
const observable = of(1, 2, 3, 4, 5).pipe(
  map((num) => of(msg + num).pipe(delay(randomDelay(1, 4) * 1000))),
  //merge values from inner observable
  concatAll()
);

observable.subscribe((message: string) => userMessage.innerHTML = message);

Osservabili JavaScript e operatore di unione

Se, invece di visualizzare i messaggi nell’ordine in cui vengono eseguiti i loro osservabili, volessimo visualizzarli mentre sono completi, potremmo usare il unire operatore. È più efficiente di concatena In ciò unire crea subito tutti gli osservabili e quindi emette il loro output ai sottoscrittori non appena vengono completati. In questo senso, gli osservabili vengono ancora eseguiti nell’ordine elencato, ma il loro output viene passato una volta emesso. Ecco lo stesso frammento di codice visto in precedenza, usando unire:

// helper method
const delayedMessage = (message: string, delayedTime: number) => 
  EMPTY.pipe(startWith(message), delay(delayedTime));

const mergeMessage="Merge message ";
merge(
  delayedMessage(mergeMessage + 1, 1000),
  delayedMessage(mergeMessage + 2, 3000),
  delayedMessage(mergeMessage + 3, 2000),
  delayedMessage(mergeMessage + 4, 1000),
  delayedMessage(mergeMessage + 5, 4000),
  // clear the screen
  delayedMessage('', 6000)
)
.subscribe((message: any) => userMessage.innerHTML = message);

Ora, invece di vedere i messaggi nell’ordine di creazione di 1, 2, 3, 4, 5, appaiono in ordine di tempo di esecuzione, vale a dire 1000 (1), 1000 (4), 2000 (3), 3000 (2), 4000 (5). Un’altra ramificazione dell’uso unire è che il messaggio a schermo libero deve avere un tempo di esecuzione più lungo rispetto agli altri messaggi.

Combinazione di flussi così come vengono emessi utilizzando unisciTutti

Il unire l’operatore ha anche un equivalente unisciTutti per combinare diversi flussi osservabili interni ed emettere contemporaneamente tutti i valori del flusso di input. Piace concatAll, unisciTutti prende flussi interni (osservabili) e li emette come un nuovo flusso, che chiameremmo osservabili di ordine superiore.

Ecco il precedente concatAll esempio aggiornato per impiegare unisciTutti:

// helper method
const delayedMessage = (message: string, delayedTime: number) => 
  EMPTY.pipe(startWith(message), delay(delayedTime));

btnMergeAll.addEventListener("click", (ev: MouseEvent) => {
  const msg = 'MergeAll message ';
  const observable = 
   of(1, 2, 3, 4, 5).pipe(
    map((num) => of(msg + num).pipe(delay(randomDelay(1, 4) * 1000))),
    //merge values from inner observable
    mergeAll()
  );

  observable.subscribe((message: string) => userMessage.innerHTML = message);
});

A causa del ritardo casuale, i cinque flussi precedenti possono essere emessi in qualsiasi ordine. Allo stesso modo, i flussi successivi che hanno lo stesso ritardo si sovrapporranno in modo che il primo venga immediatamente eclissato dal secondo.

Ti piace vedere i frammenti di codice sopra in azione? C’è una demo su stackblitz.com.

Concatenamento di osservabili RxJS

Questo blog ha presentato alcune opzioni per concatenare gli osservabili da eseguire in un ordine specifico. Una volta che ci hai preso la mano, puoi combinarli con operatori di trasformazione come carta geografica, mergeMap, switchMap, e mappa piatta per produrre osservabili di ordine superiore che si adattano meglio alle vostre esigenze specifiche.

Source link

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.