JSFiddle - React, Tailwind, and code Playground
by nomadev
TypeScript
import { UserResponse } from '../../../types/user/user-response';
import { AlertUser } from '../../../types/user/alert-user';
import { Injectable } from '@angular/core';
import { of, timer, Observable, Subject, AsyncSubject, BehaviorSubject } from 'rxjs';
import { tap, switchMap, map, take, filter } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class AlertUserService {
private sending = false;
/**
* la coda di alert è composta da un AsyncSubject e da un BehaviourSubject.
* Ciò che viene ritornato dalla funzione pubblica "send" è l'AsyncSubject. Tale scelta
* è dovuta alla proprietà di AsyncSubject di emettere il suo valore agli observer solo DOPO che il subject viene
* completato
*/
private queue: [AsyncSubject<UserResponse>, BehaviorSubject<AlertUser>] [] = [];
/**
* Un semplice Subject viene creato per conservare l'alert da mostrare.
*/
private subject = new Subject();
/**
* Il subject contenente il messaggio viene esposto pubblicamente come un observable readonly
*/
public readonly message = this.subject.asObservable();
private sender(): Observable<boolean> {
// prendo il primo elemento della coda
const a$ = this.queue.shift();
if (! a$ ) this.sending = false;
else {
/** se la coda non è vuota compongo un observable che inizia con un timer di 500ms.
* Il timer serve anche come piccola pausa tra questo alert e l'eventuale precedente
*/
this.sending = true;
timer(500).pipe(
/**
* passo dall'observable timer al BS del messaggio da mostrare
*/
switchMap(res => a$[1]),
/**
* assegno al subject esposto pubblicamente, il contenuto di questo alert
*/
tap( res => this.subject.next(res)),
/**
* Mentre il...