Appearance
Comment utiliser concatMap sur RxJS ?
Voici un exemple:
javascript
import { interval, timer, take, concatMap, map } from 'rxjs';
const source = interval(50).pipe(take(5));
const result = source.pipe(
concatMap(value =>
timer(Math.random() * 1000).pipe(map(() => value))
)
);
result.subscribe(
message => console.log(message),
error => console.error('Erreur :', error),
() => console.log('Toutes les opérations sont terminées')
);
Explication du code
Création de l'observable source :
interval(50)
crée un observable qui émet des valeurs séquentielles (0, 1, 2, 3, 4, ...) toutes les 50 millisecondes.take(5)
limite cette émission à 5 valeurs (0, 1, 2, 3, 4).
Utilisation de
concatMap
:concatMap
est utilisé pour transformer chaque valeur émise parsource
en un nouvel observable.- La fonction de projection crée un
timer
qui attend un temps aléatoire (jusqu'à 1000 millisecondes) avant d'émettre la valeur.
Souscription :
- On souscrit à
result
pour afficher chaque valeur une fois que le timer pour cette valeur a terminé. - Une fois que toutes les valeurs ont été traitées, le message "Toutes les opérations sont terminées" est affiché.
- On souscrit à
Intérêt de concatMap
L'intérêt principal de concatMap
dans ce contexte est d'assurer que les opérations asynchrones (ici, les temporisations aléatoires avec timer
) sont exécutées séquentiellement et dans l'ordre des valeurs émises par source
.
Points clés de concatMap
:
Séquence d'exécution :
concatMap
garantit que chaque nouvelle valeur n'est traitée qu'après que l'observable précédent a complété son émission. Même si les valeurs sont émises toutes les 50 millisecondes parinterval
, les timers introduits partimer
sont exécutés de manière séquentielle.Ordre préservé : Les valeurs sont émises dans l'ordre exact où elles ont été reçues par
concatMap
. Ceci est important pour maintenir l'ordre des opérations asynchrones, évitant des interférences ou des exécutions en parallèle qui pourraient déstructurer l'ordre initial.
Comparaison avec d'autres opérateurs
mergeMap
: Si vous utilisiezmergeMap
à la place deconcatMap
, les timers seraient exécutés en parallèle. Les valeurs pourraient être émises dans un ordre différent de celui dans lequel elles ont été émises parsource
.switchMap
: UtiliserswitchMap
annulerait le timer en cours dès qu'une nouvelle valeur est émise, ne permettant pas d'attendre la fin du timer précédent avant de commencer un nouveau.
Bien sûr ! Prenons un autre exemple pour illustrer l'utilisation de concatMap
dans un contexte différent.
Exemple de téléchargement séquentiel de fichiers
Imaginez que vous avez une liste de fichiers à télécharger et que vous voulez vous assurer que chaque fichier est téléchargé séquentiellement.
Voici comment vous pouvez utiliser concatMap
pour gérer cela :
javascript
import { from, concatMap, ajax } from 'rxjs';
// Liste des URLs de fichiers à télécharger
const fileUrls = [
'https://example.com/file1',
'https://example.com/file2',
'https://example.com/file3'
];
// Observable émettant les URLs de fichiers
const filesObservable = from(fileUrls);
// Fonction qui retourne un observable représentant une requête de téléchargement de fichier
const downloadFile = (url) => ajax.getJSON(url);
// Utilisation de concatMap pour gérer les téléchargements séquentiellement
const result = filesObservable.pipe(
concatMap(url => {
console.log(`Téléchargement du fichier : ${url}`);
return downloadFile(url);
})
);
// Souscription au résultat pour afficher les données de chaque fichier
result.subscribe(
data => console.log('Données du fichier téléchargé :', data),
error => console.error('Erreur de téléchargement :', error),
() => console.log('Tous les fichiers ont été téléchargés')
);
Cas d'utilisation
Titre | Description |
---|---|
Téléchargement séquentiel | Télécharge une liste de fichiers séquentiellement, en attendant que chaque téléchargement se termine avant de commencer le suivant. |
Opérations retardées | Gère des tâches avec des délais aléatoires, assurant une exécution séquentielle pour chaque tâche retardée. |
Traitement de tâches par lots | Traite des tâches par lots, en veillant à ce qu'un lot de tâches soit terminé avant de commencer le suivant. |
Envoi de messages | Envoie des messages à une file d'attente ou à un serveur, en s'assurant qu'un message est complètement envoyé avant d'envoyer le suivant. |
Mise à jour de base de données | Effectue des mises à jour séquentielles dans une base de données, garantissant qu'une mise à jour est terminée avant de commencer la suivante. |
Animation séquentielle | Enchaîne des animations, s'assurant qu'une animation se termine avant de commencer la suivante. |
Lecture séquentielle de fichiers | Lit des fichiers séquentiellement, garantissant qu'une lecture de fichier se termine avant de commencer la suivante. |
Appels API séquentiels | Effectue des appels API de manière séquentielle, s'assurant que chaque appel API est complété avant de commencer le suivant. |
Traitement séquentiel de formulaires | Traite les soumissions de formulaires séquentiellement, garantissant que chaque soumission est traitée avant de passer à la suivante. |
Gestion de flux de tâches | Gère un flux de tâches où chaque tâche doit être complétée avant de passer à la suivante, assurant une gestion ordonnée des tâches. |