Est-il nécessaire de se désabonner des observables créés par les méthodes Http?
avez-vous besoin de vous désabonner des appels http Angular 2 pour éviter les fuites de mémoire?
fetchFilm(index) {
var sub = this._http.get(`http://example.com`)
.map(result => result.json())
.map(json => {
dispatch(this.receiveFilm(json));
})
.subscribe(e=>sub.unsubscribe());
...
6 réponses
donc la réponse est non, vous ne le faites pas. Ng2
nettoiera tout seul.
Le service Http de la source, à partir Angulaire Http XHR backend source:
remarquez comment fonctionne le complete()
après avoir obtenu le résultat. Cela signifie qu'il se désabonne en fait à l'achèvement. Si vous n'avez pas besoin de le faire vous-même.
Voici un test pour valider:
fetchFilms() {
return (dispatch) => {
dispatch(this.requestFilms());
let observer = this._http.get(`${BASE_URL}`)
.map(result => result.json())
.map(json => {
dispatch(this.receiveFilms(json.results));
dispatch(this.receiveNumberOfFilms(json.count));
console.log("2 isUnsubscribed",observer.isUnsubscribed);
window.setTimeout(() => {
console.log("3 isUnsubscribed",observer.isUnsubscribed);
},10);
})
.subscribe();
console.log("1 isUnsubscribed",observer.isUnsubscribed);
};
}
comme prévu, vous pouvez voir qu'il est toujours désabonné automatiquement après avoir obtenu le résultat et de finir avec les opérateurs observables. Cela se produit sur un timeout (#3) de sorte que nous pouvons vérifier l'état de l'observable lorsque tout est terminé et complété.
et le résultat
donc, aucune fuite n'existerait comme Ng2
auto désabonnement!
Nice to mention: Cette Observable
est classé comme finite
, contrairement à la infinite
Observable
qui est un infini de flux de données peuvent être émis comme DOM click
port d'écoute par exemple.
merci, @rubyboy pour l'aide.
appeler la méthode unsubscribe
revient plutôt à annuler une requête HTTP en cours puisque cette méthode appelle la abort
sur l'objet XHR sous-jacent et supprime les écouteurs sur les événements de charge et d'erreur:
// From the XHRConnection class
return () => {
_xhr.removeEventListener('load', onLoad);
_xhr.removeEventListener('error', onError);
_xhr.abort();
};
qui dit, unsubscribe
supprime les auditeurs... Donc ça pourrait être une bonne idée mais je ne pense pas que ce soit nécessaire pour une seule requête; -)
J'espère que ça vous aidera, Thierry
de quoi parlez-vous?!!
OK donc il y a deux raisons fondamentales pour se désabonner de tout observable. Personne ne parle beaucoup de la seconde!
1) Nettoyer les ressources. Comme d'autres l'ont dit, il s'agit d'un problème négligeable pour les observables HTTP. Il va tout simplement de nettoyer lui-même.
2) empêcher le manipulateur
subscribe
d'être exécuté.
le l'importance du numéro 2 va dépendre de ce que fait votre gestionnaire:
si votre fonction de gestionnaire
subscribe()
a un effet secondaire indésirable lorsque le composant appelant est fermé, vous devez vous désabonner (ou ajouter une logique conditionnelle) pour l'empêcher d'être appelé.
Envisager un certain nombre de cas:
1) un formulaire de connexion. Vous entrez le nom d'utilisateur et le mot de passe et cliquez sur "Login". Que faire si le serveur est lent et vous décidez de cliquer sur Escape pour fermer le dialogue? Vous supposerez probablement que vous n'avez pas été connecté, mais si la requête http est revenue après que vous ayez frappé escape, alors vous exécuterez toujours la logique que vous avez là. Cela peut se traduire par une redirection, un cookie de connexion indésirable ou une variable token étant définie. Ce n'est probablement pas ce que votre utilisateur prévu.
2) un formulaire "envoyer un courriel". Une fois que le message HTTP est en vol, il est important de comprendre que unsubscribe()
n'annulera pas la requête HTTP. Il est déjà sur son chemin - et ce n'est rien à voir avec Angular ou RxJS - c'est juste comment l'internet fonctionne. Il permettra d'accéder à votre serveur, et l'e-mail sera envoyé. (Vous devrez mettre en œuvre une sorte de mécanisme d'envoi différé comme le fait le bouton Annuler de Gmail si vous avez besoin d'un comportement plus sophistiqué.)
si le handler subscribe
pour ' sendEmail' fait quelque chose comme déclencher une animation 'votre e-mail est envoyé', vous transférer à un autre route ou accès à un autre observable qui a été disposé alors vous obtiendrez des exceptions ou un comportement indésirable.
parfois, vous pouvez être quelque part entre des actions que vous voudriez et d'autres que vous ne voudriez pas. Par exemple, vous avez peut-être un son 'swoosh' pour un e-mail envoyé. Vous voudriez probablement que cela fonctionne même si le component était fermé, mais si vous essayez d'exécuter une animation sur le component qui est juste fermé, cela échouerait. Dans ce cas, une logique extra-conditionnelle inside subscribe serait la solution - et vous ne voudriez pas vous désabonner du http observable.
donc en réponse à la question actuelle, Non vous n'avez pas besoin de le faire pour éviter les fuites de mémoire. Mais vous devez le faire (généralement) pour éviter les effets secondaires indésirables étant déclenché ou le code courant qui peut jeter exceptions et même corrompre l'état de votre application.
Tip: le Subscription
contient une propriété booléenne closed
qui peut être utile dans certains cas. Pour HTTP, ceci sera défini lorsqu'il sera terminé. Aussi parfois, il peut être utile de définir une propriété _isDestroyed
après la destruction d'un composant que subscribe
peut vérifier pour décider ce qu'il ne faut pas exécuter.
vous ne devez pas vous désabonner des observables qui se remplissent automatiquement (E. G Http, appels). Mais il est nécessaire de se désabonner des observables infinis comme Observable.timer()
.
RxJS observable sont fondamentalement associés et fonctionnent en conséquence vous l'souscrivez. Lorsque nous créons l'observable et le mouvement nous le complétons, observable se ferme automatiquement et se désabonne.
nous n'avons pas à invoquer explicitement la méthode de désabonnement.vous pouvez vérifier l'état de observable en utilisant la méthode fermée.