테이크(1) 대 퍼스트 클래스
의 몇 가지 구현을 찾았습니다.AuthGuard
그것을 사용자take(1)
내 프로젝트에서, 나는 사용했습니다.first()
.
둘 다 같은 방식으로 작동합니까?
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)
}
}
연자first()
그리고.take(1)
같지 않습니다.
그first()
인 연자는선사사용니합다을항을 사용합니다.predicate
, 기하고방니다합출능을 합니다.error
소스가 완료되었을 때 일치하는 값이 없을 때 알림.
예를 들어 다음과 같은 오류가 발생합니다.
import { EMPTY, range } from 'rxjs';
import { first, take } from 'rxjs/operators';
EMPTY.pipe(
first(),
).subscribe(console.log, err => console.log('Error', err));
뿐만 아니라 다음과 같습니다.
range(1, 5).pipe(
first(val => val > 6),
).subscribe(console.log, err => console.log('Error', err));
이 값은 처음 방출된 값과 일치합니다.
range(1, 5).pipe(
first(),
).subscribe(console.log, err => console.log('Error', err));
에 ㅠㅠㅠtake(1)
첫 번째 값을 가져와서 완료합니다.더 이상의 논리는 관여하지 않습니다.
range(1, 5).pipe(
take(1),
).subscribe(console.log, err => console.log('Error', err));
그러면 관측 가능한 빈 소스를 사용하면 오류가 발생하지 않습니다.
EMPTY.pipe(
take(1),
).subscribe(console.log, err => console.log('Error', err));
2019년 1월: RxJS 6용으로 업데이트됨
팁: 사만만 하세요.first()
다음과 같은 경우:
- 0개의 항목이 방출되는 것을 오류 조건(예: 방출 전 완료)으로 간주하고 0% 이상의 오류 가능성이 있을 경우 정상적으로 처리합니다.
- 또는 관측 가능한 소스가 1개 이상의 항목을 방출한다는 것을 100% 알고 있습니다(따라서 절대 던질 수 없음).
인 경우 하지 않는 배이이 0고와 0로으적처리경않우지는(with 출량함 0하명시께와이▁if함)catchError
그러면 오류가 전파되어 다른 곳에서 예기치 않은 문제가 발생할 수 있으며 특히 최종 사용자가 보낸 오류일 경우 추적하기가 매우 까다로울 수 있습니다.
사용하는 것이 더 안전합니다.take(1)
대부분의 경우, 다음과 같은 경우:
- 요.
take(1)
소스가 방출 없이 완료되면 아무것도 방출하지 않습니다. - 인라인 서술어를 사용할 필요가 없습니다(예:
first(x => x > 10)
)
참고: 술어는 다음과 같이 사용할 수 있습니다.take(1)
와 같이: 과같이다음:.pipe( filter(x => x > 10), take(1) )
10보다 큰 .
때어는?single()
만약 당신이 더 엄격해지고 싶다면, 그리고 두 개의 배출물을 허용하지 않는다면 당신은 사용할 수 있습니다.single()
0개 또는 2개 이상의 배출물이 있는 경우 어떤 오류가 발생하는지 확인합니다.이 경우에도 오류를 처리해야 합니다.
»:Single
관찰 가능한 체인이 http 서비스를 두 번 호출하고 관찰 가능한 두 개를 내보내는 것과 같은 추가 작업을 수행하지 않도록 하려면 가끔 유용할 수 있습니다. 추가하기single
파이프 끝까지 당신이 그런 실수를 했는지 알려줄 것입니다.러너'에서에 '태스크 러너'를 답을 합니다.single(), catchError()
좋은 행동을 보장하기 위해.
항상사지이유를 사용하지 ?first()
에 take(1)
?
아. 게떻. 어게.first
잠재적으로 더 많은 오류를 유발할 수 있습니까?
서비스에서 무언가를 가져온 다음 파이프로 연결하는 관찰 가능한 항목이 있는 경우first()
당신은 대부분 잘 지내야 합니다. 어떤를 비활성화하기 - 을 방출하기 한다면,of(null)
또는NEVER
그 다음에는 아무 하류나.first()
작업자가 오류를 던지기 시작할 수 있습니다.
이제 저는 그것이 당신이 정확히 원하는 것일 수 있다는 것을 깨달았습니다. 그래서 이것이 단지 팁인 이유입니다.연산자first
'있게미간 '것기때clumsy ' 렸에나 '보다 '가 조금 했습니다.take(1)
그러나 소스가 방출되지 않을 가능성이 있는 경우 오류 처리에 주의해야 합니다.하지만 전적으로 당신이 무엇을 하고 있는지에 달려있습니다.
기본값(상수)이 있는 경우:
또한고니다합려도 고려해 ..pipe(defaultIfEmpty(42), first())
기본값이 있는 경우 이 값을 사용하여 아무것도 되지 않을 때 사용해야 합니다.물론 이것은 오류를 일으키지 않을 것입니다. 왜냐하면first
항상 값을 받습니다.
:defaultIfEmpty
있는 , 이 스림이비있경트우며리되, 는되값이방거출만인 않습니다.null
.
관찰할 수 있는 항목 세 가지가 있습니다.A
,B
,그리고.C
대리석 다이어그램으로 사이의 차이점을 탐구합니다.first
,take
,그리고.single
연산자:
범례:
--o--
----!
오류
----|
https://thinkrx.io/rxjs/first-vs-take-vs-single/ 에서 그것을 가지고 놀 수 있습니다.
이미 모든 답을 가지고 있기 때문에, 저는 좀 더 시각적인 설명을 덧붙이고 싶었습니다.
누군가에게 도움이 되길 바랍니다.
어디에도 언급되지 않은 정말 중요한 차이점이 하나 있습니다.
take(1)는 1을 방출하고, 완료하며, 구독 취소
첫 번째 메시지는 1을 내보내고 완료하지만 구독을 취소하지 않습니다.
이는 업스트림 관찰 가능한 것이 첫 번째() 이후에도 여전히 뜨겁다는 것을 의미하며, 이는 예상치 못한 동작일 수 있습니다.
UPD: RxJS 5.2.0을 참조합니다.이 문제는 이미 해결되었을 수 있습니다.
에서는 RxJS 5.2.0이 사용되는 것 ..first()
오퍼레이터가 버그가 있습니다.
에 ㅠㅠㅠㅠㅠㅠㅠ.take(1)
그리고..first()
때 에서사는매경다동수있작습니다할르게우우용하▁quite와 함께 동작할 수 .switchMap
:
와 함께take(1)
하게 될 입니다: 대로동됩니다게작하예상됩다.
var x = Rx.Observable.interval(1000)
.do( x=> console.log("One"))
.take(1)
.switchMap(x => Rx.Observable.interval(1000))
.do( x=> console.log("Two"))
.subscribe((x) => {})
// In the console you will see:
// One
// Two
// Two
// Two
// Two
// etc...
하지만 함께.first()
잘못된 행동을 하게 될 것입니다.
var x = Rx.Observable.interval(1000)
.do( x=> console.log("One"))
.first()
.switchMap(x => Rx.Observable.interval(1000))
.do( x=> console.log("Two"))
.subscribe((x) => {})
// In console you will see:
// One
// One
// Two
// One
// Two
// One
// etc...
여기 코데펜에 대한 링크가 있습니다.
두 방법 사이에는 매우 중요한 차이가 있습니다. 값이 나오기 전에 스트림이 완료되면 첫 번째()에서 오류가 발생합니다.또는 술어를 제공한 경우(i.e. first(value => value === 'foo'))
서술어를 통과하는 값이 나오기 전에 스트림이 완료되면 오류가 발생합니다.
반면에 take(1)는 스트림에서 값이 방출되지 않는 경우 행복하게 계속됩니다.다음은 간단한 예입니다.
const subject$ = new Subject();
// logs "no elements in sequence" when the subject completes
subject$.first().subscribe(null, (err) => console.log(err.message));
// never does anything
subject$.take(1).subscribe(console.log);
subject$.complete();
다른 예제, 술어 사용:
const observable$ = of(1, 2, 3);
// logs "no elements in sequence" when the observable completes
observable$
.first((value) => value > 5)
.subscribe(null, (err) => console.log(err.message));
// the above can also be written like this, and will never do
// anything because the filter predicate will never return true
observable$
.filter((value) => value > 5);
.take(1)
.subscribe(console.log);
RxJS에 새로 온 사람으로서, 비록 제가 잘못된 추측을 했기 때문에 제 자신의 잘못이었지만, 이 행동은 저에게 매우 혼란스러웠습니다.제가 서류를 확인하려고 했다면, 그 행동이 명확하게 문서화되어 있다는 것을 알 수 있었을 것입니다.
다음과 같은 경우 오류를 발생시킵니다.
defaultValue
제공되지 않았으며 일치하는 요소를 찾을 수 없습니다.
제가 이것을 자주 마주치는 이유는 관찰 가능한 것들이 수동으로 정리되는 꽤 흔한 Angular 2 패턴 때문입니다.OnDestroy
수명 주기 후크:
class MyComponent implements OnInit, OnDestroy {
private stream$: Subject = someDelayedStream();
private destroy$ = new Subject();
ngOnInit() {
this.stream$
.takeUntil(this.destroy$)
.first()
.subscribe(doSomething);
}
ngOnDestroy() {
this.destroy$.next(true);
}
}
코드는 처음에는 해롭지 않아 보이지만 이전에 구성 요소가 파괴되었을 때 문제가 발생합니다.stream$
값을 방출할 수 있습니다.사용하고 있기 때문에first()
구성 요소가 파괴될 때 오류가 발생합니다.일반적으로 구성 요소 내에서 사용할 값을 얻기 위해 스트림만 구독하기 때문에 스트림이 방출되기 전에 구성 요소가 파괴되어도 상관 없습니다.이것 때문에, 저는 사용하기 시작했습니다.take(1)
곳에서.first()
.
filter(fn).take(1)
보다 조금 더 장황합니다.first(fn)
그러나 대부분의 경우 애플리케이션에 궁극적으로 영향을 미치지 않는 오류를 처리하는 것보다 조금 더 자세한 내용을 선호합니다.
또한 주의해야 할 사항은 다음과 같습니다.동일한 내용이 적용됩니다.last()
그리고.takeLast(1)
.
언급URL : https://stackoverflow.com/questions/42345969/take1-vs-first
'source' 카테고리의 다른 글
어떤 경우에 Oracle은 자동으로 인덱스를 생성합니까? (0) | 2023.06.08 |
---|---|
Windows zure에서 Ocp-Apim-Subscription-Key를 찾을 수 있는 위치 (0) | 2023.06.03 |
원격 연결을 수신하기 위해 Linux에서 MongoDB 가져오기 (0) | 2023.06.03 |
소수점 정밀도 및 척도(EF Code First) (0) | 2023.06.03 |
미디어 쿼리:데스크톱, 태블릿 및 모바일을 대상으로 하는 방법은 무엇입니까? (0) | 2023.06.03 |