1. ホーム
  2. angular

[解決済み】take(1) vs first()

2022-04-23 01:49:48

質問

の実装をいくつか見つけました。 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));

そうすると、ソースが空のObservableでは、エラーは出ません。

EMPTY.pipe(
  take(1),
).subscribe(console.log, err => console.log('Error', err));

2019年1月:RxJS 6に対応した更新を行いました。