我发现了一些AuthGuard使用 s 的实现take(1)。在我的项目中,我使用了first().
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
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));
然后使用空源 Observable 它不会发出任何错误:
EMPTY.pipe( take(1), ).subscribe(console.log, err => console.log('Error', err));
2019 年 1 月:针对 RxJS 6 更新