Elles peuvent se produire quand on lance N requêtes dont seul un résultat nous intéresse. Le problème survient quand on peut avoir ces N requêtes en parallèle, typiquement parce qu'on ne peut pas annuler la requête précédente avant dans lancer une autre.
Par exemple si je lance 3 "getProducts" d'affilé, et que le premier répond en 1000 ms, le second en 800 ms et le troisième en 900ms, alors je recevrai dans cet ordre :
- résultat 2
- résultat 3
- résultat 1
En général, sans protection, je vais faire les mises à jour au moment où je reçois les résultats, et l'utilisateur aura alors le mauvais affichage final (c'était le résultat 3 qui m'intéressait) 😥
On peut soit :
- annuler la requête en cours s'il y en a une, avant d'en lancer une autre → pas de souci !
- si c'est impossible, il faut se donner le moyen d'identifier à quelle requête appartient tel résultat, ainsi comme on sait quelle est la dernière requête envoyée, lorsqu'on reçoit un résultat si on peut savoir s'il est effectivement le résultat de cette dernière requête, alors on peut tout simplement ignorer les autres
Dans notre exemple :
- requête 1
- requête 2
- requête 3 ← c'est la dernière requête
- résultat 2 → lié à requête 2 → ignoré
- résultat 3 → lié à requête 3 → traité
- résultat 1 → lié à requête 1 → ignoré
Peu importe l'ordre dans lequel les résultats arrivent, on peut les traiter ou les ignorer de manière pertinente.
- On garde une référence vers la notion de "dernière requête"
- Lors du démarrage d'une requête, on met dans cette référence une valeur qui représente de manière unique cette requête
- Lorsque la requête se termine, on vérifie si la valeur qui est dans cette référence correspond toujours à notre identifiant de requête
- si non, c'est qu'une autre requête s'est intercalée et on ignore le résultat
- si oui, c'est le résultat attendu, on traite le résultat
Dans notre exemple de "getProducts" une valeur qui permet d'identifier uniquement la requête est typiquement la catégorie (voir la modification sur ProductList.js
), et on peut implémenter un algorithme similaire dans notre useAsync
aussi bien que dans Redux (et c'est vraiment utile dans la vraie vie 😇).