Je suis actuellement confronté à un problème, où une première recherche peut prendre 5 secondes et une seconde qui prend 2 secondes, le problème est que la première recherche qui prend plus de temps "effacera" les résultats de la requête qui a été effectuée après, car les appels se terminent après.
J'ai essayé de lire sur
switchMap
dans rxJs et j'ai essayé de l'utiliser, mais d'après ce que j'essaye, il ne se désabonne pas de la demande précédente et efface le résultat.
Il y a probablement quelque chose que je fais mal ici, mais je ne peux pas indiquer exactement quel est le problème.
La fusion a 3 sources de changement dans le résultat (pagination, tri ou nouveaux critères de recherche), et le call to sendSearchCriteria renvoie les données utilisées.
sendSearchCriteria renvoie un Observable
y a-t-il quelque chose qui me vient à l'esprit, que je fais mal?
Merci pour votre aide,
private loadDogsResults = (filtersInformation: FilterSearchCriteria) => { merge(this.sort.sortChange, this.paginator.page, of(filtersInformation)) .pipe( distinctUntilChanged(), tap(() => (this.isLoading = true)), switchMap(() => this.sendSearchCriteria(filtersInformation)), //mergeMap(() => this.sendSearchCriteria(filtersInformation)), map(data => this.formatResults(data)), finalize(() => (this.isLoading = false)), catchError(error => this.handleError(error)), takeUntil(this._onDestroy$) ) .subscribe((result: any[]) => { if (result.length > 0) { this.setDisplayedColumns(result[0]); } this.isLoading = false; }); }
3 Réponses :
Quel événement déclenche la recherche
? Cet événement doit être la source de votre Observable
, qui sera "canalisé" avec l'opérateur switchMap
.
Comme je peux le voir ici, si vous appelez loadDogsResults ()
pour chaque événement, cela ne fonctionnera pas car vous créez un nouvel Observable
à chaque fois. of (filtersInformation)
est un observable qui émet la valeur filtersInformation
UNE FOIS lorsque l'observable est abonné, je ne pense pas que ce soit le comportement attendu.
Merci, en effet ce n'était pas le cas, cela a conduit à la solution que j'ai postée :) merci beaucoup!
Vous effectuez une fusion sur 3 observables distincts, ce qui vous permettra d'entrer dans le tube à 3 reprises et de lancer 3 appels distincts à sendSearchCriteria. Si vous voulez appeler sortChange et page, obtenir les résultats des deux puis appeler sendSearchCriteria, vous pouvez ...
private loadDogsResults = (filtersInformation: FilterSearchCriteria) => { forkJoin(this.sort.sortChange, this.paginator.page) .pipe( distinctUntilChanged(), tap(() => (this.isLoading = true)), switchMap(() => this.sendSearchCriteria(filtersInformation)), //mergeMap(() => this.sendSearchCriteria(filtersInformation)), map(data => this.formatResults(data)), finalize(() => (this.isLoading = false)), catchError(error => this.handleError(error)), takeUntil(this._onDestroy$) ) .subscribe((result: any[]) => { if (result.length > 0) { this.setDisplayedColumns(result[0]); } this.isLoading = false; }); }
Cependant, gardez à l'esprit que dans votre abonnement, vous n'aurez accès qu'à à la réponse de sendSearchCriteria.
Je vous remercie ! Le problème était plus dû à l'initialisation mais en effet la fusion était un problème, merci pour le lead, cfr: solution postée!
Un collègue m'a aidé à trouver le problème :) nous avons essayé forkJoin, combineLatest et plusieurs options, mais le plus gros problème était l'initialisation / l'abonnement effectué d'une manière étrange.
Nous avons maintenant créé un searchTriggerSubject et ajouté ces lignes
< pre> XXXles filtres venaient d'un service, c'est donc ce que nous avons fait pour éviter le problème.
Une refactorisation était nécessaire
Merci beaucoup à tous pour les différents prospects, avoir plusieurs sujets facilite les choses
Ce que vous décrivez est exactement le cas d’utilisation de switchMap, il annule les requêtes en cours qui sont anciennes et même si ce n’est pas le cas, il ignore leurs résultats.
oui mais c'est le problème, cela ne fonctionne pas comme je le souhaiterais, la requête n'est pas annulée et les résultats sont pris, même avec l'utilisation de switchMap commenté: /
Essayez de créer un exemple minimal reproductible sur stackblitz.io - à partir d'un test rapide avec les éléments http et switchMap d'angular semblent fonctionne normalement. Votre princesse est dans un autre château, quelque chose d'autre ne va pas avec votre code.
Notez que
mergeMap
(que vous avez ici au lieu de switchMap) ne fonctionnera absolument pas pour cela et n'annulera pas l'événement - c'est par conception.oui, en décommentant switchMap, je commente le mergeMap, ce qui n'aide pas :(
un collègue m'a envoyé un stackblitz.io qui fonctionne bien pour le cas d'utilisation de switchMap, mais malheureusement cela ne m'aide pas à voir plus clairement ce qui ne va pas dans mon code stackblitz.com/edit/rxjs-ui3che
Je ne peux vraiment rien vous aider si le stackblitz est un exemple fonctionnel - je sais déjà que switchMap fonctionne dans stackblitz:] Désolé et que les dieux du débogage soient en votre faveur.
merci :) J'espère que je parviendrai à le résoudre!
Que renvoie
sendSearchCriteria
ou comment crée-t-il l'appel à distance? Afin de faire fonctionnerswitchMap
dans les besoins de renvoyer un abonnement, chat peut être désabonné.@ Dinosan0908 Comment est appelé
loadDogsResults
? Est-il appelé une seule fois ou l'appelez-vous plusieurs fois (par exemple, chaque fois quefiltersInformation
change)?merci les gars, solution trouvée grâce à toutes les idées!