Ich habe einige Implementierungen von AuthGuard
s gefunden, die diese verwenden take(1)
. In meinem Projekt habe ich verwendet first()
.
Arbeiten beide gleich?
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/first';
import { Observable } from 'rxjs/Observable';
import { Injectable } from '@angular/core';
import { CanActivate, Router, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { AngularFire } from 'angularfire2';
@Injectable()
export class AuthGuard implements CanActivate {
constructor(private angularFire: AngularFire, private router: Router) { }
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | boolean {
return this.angularFire.auth.map(
(auth) => {
if (auth) {
this.router.navigate(['/dashboard']);
return false;
} else {
return true;
}
}
).first(); // Just change this to .take(1)
}
}
angular
rxjs
angular2-observables
Karuban
quelle
quelle
first()
undtake()
bin im Allgemeinen gleich, was ich für offensichtlich halte, nur dasfirst()
undtake(1)
sind gleich. Ich bin mir anhand Ihrer Antwort nicht sicher, ob Sie glauben, dass es noch einen Unterschied gibt?first()
senden Sie eine Fehlerbenachrichtigung, während Sietake(1)
einfach nichts ausgeben.first()
. Wenn es ein gültiger Anwendungsstatus ist, würde ich mit gehentake(1)
..First()
vs.FirstOrDefault()
(und denken Sie auch daran,.Take(1)
dass First etwas in der Sammlung benötigt und einen Fehler für eine leere SammlungFirstOrDefault()
.Take(1)
null
Tipp: Nur verwenden,
first()
wenn:Wenn es keine Emissionen gibt und Sie nicht explizit damit umgehen (mit
catchError
), wird sich dieser Fehler ausbreiten, möglicherweise ein unerwartetes Problem an einer anderen Stelle verursachen und es kann ziemlich schwierig sein, ihn aufzuspüren - insbesondere, wenn er von einem Endbenutzer stammt.Sie sind größtenteils sicherer ,
take(1)
vorausgesetzt, dass:take(1)
nichts aussenden, wenn die Quelle ohne Emission abgeschlossen ist.first(x => x > 10)
)Hinweis: Sie können ein Prädikat
take(1)
wie folgt verwenden :.pipe( filter(x => x > 10), take(1) )
. Dies ist kein Fehler, wenn nichts größer als 10 ist.Wie wäre es mit
single()
Wenn Sie noch strenger sein und zwei Emissionen nicht zulassen möchten, können Sie
single()
welche Fehler verwenden, wenn es keine oder mehr Emissionen gibt . Auch in diesem Fall müssten Sie Fehler behandeln.Tipp:
Single
Kann gelegentlich nützlich sein, wenn Sie sicherstellen möchten, dass Ihre beobachtbare Kette keine zusätzliche Arbeit leistet, z. B. zweimal einen http-Dienst aufruft und zwei beobachtbare Elemente ausgibt. Wenn Siesingle
am Ende des Rohrs hinzufügen, werden Sie informiert, wenn Sie einen solchen Fehler gemacht haben. Ich verwende es in einem 'Task Runner', in dem Sie eine beobachtbare Aufgabe übergeben, die nur einen Wert ausgeben sollte. Daher leite ich die Antwort weitersingle(), catchError()
, um ein gutes Verhalten zu gewährleisten.Warum nicht immer
first()
statt verwendentake(1)
?aka. Wie kann
first
möglicherweise mehr Fehler verursachen?Wenn Sie ein Observable haben, das etwas von einem Service nimmt und es dann durchleitet, sollte es
first()
Ihnen die meiste Zeit gut gehen. Aber wenn jemand kommt , den Service für welchen Gründen auch immer zu deaktivieren - und ändert es emittierenof(null)
oderNEVER
dann alle nachgelagertenfirst()
Betreiber beginnen würde , Fehler zu werfen.Jetzt ist mir klar, dass dies genau das sein könnte , was Sie wollen - daher ist dies nur ein Tipp. Der Betreiber hat
first
mich angesprochen, weil es etwas weniger "ungeschickt" klang als,take(1)
aber Sie müssen vorsichtig mit Fehlern umgehen, wenn jemals die Möglichkeit besteht, dass die Quelle nicht emittiert. Wird ganz davon abhängen, was Sie tun.Wenn Sie einen Standardwert (Konstante) haben:
Überlegen Sie auch,
.pipe(defaultIfEmpty(42), first())
ob Sie einen Standardwert haben, der verwendet werden soll, wenn nichts ausgegeben wird. Dies würde natürlich keinen Fehler auslösen, dafirst
immer ein Wert erhalten würde.Beachten Sie, dass dies
defaultIfEmpty
nur ausgelöst wird, wenn der Stream leer ist, nicht wenn der Wert der ausgegebenen Daten istnull
.quelle
single
es mehr Unterschiede zu gibtfirst
. 1. Es wird nur der Wert on ausgegebencomplete
. Dies bedeutet, dass wenn das Observable einen Wert ausgibt, aber niemals abgeschlossen wird, Single niemals einen Wert ausgibt. 2. Wenn Sie aus irgendeinem Grund eine Filterfunktion übergeben,single
die mit nichts übereinstimmt, wird einundefined
Wert ausgegeben , wenn die ursprüngliche Sequenz nicht leer ist, was bei nicht der Fall istfirst
.Hier sind drei Observable
A
,B
undC
mit Marmor Diagramme , die den Unterschied zwischen zu erkundenfirst
,take
undsingle
Operatoren:* Legende :
--o--
Wert----!
Fehler----|
AbschlussSpielen Sie damit unter https://thinkrx.io/rxjs/first-vs-take-vs-single/ .
Da ich bereits alle Antworten hatte, wollte ich eine visuellere Erklärung hinzufügen
Hoffe es hilft jemandem
quelle
Es gibt einen wirklich wichtigen Unterschied, der nirgendwo erwähnt wird.
take (1) gibt 1 aus, schließt ab, meldet sich ab
first () gibt 1 aus, wird abgeschlossen, aber nicht abgemeldet.
Dies bedeutet, dass Ihr Upstream-Observable nach first () immer noch heiß ist, was wahrscheinlich nicht zu erwarten ist.
UPD: Dies bezieht sich auf RxJS 5.2.0. Dieses Problem ist möglicherweise bereits behoben.
quelle
Es scheint, dass in RxJS 5.2.0 der
.first()
Operator einen Fehler hat ,Aufgrund dieses Fehlers
.take(1)
und.first()
kann sich ganz anders verhalten, wenn Sie sie verwenden mitswitchMap
:Mit erhalten
take(1)
Sie Verhalten wie erwartet:Aber mit
.first()
dir wirst du falsches Verhalten bekommen:Hier ist ein Link zum Codepen
quelle