我每天都在使用的十個(gè) RxJS 運(yùn)算符
作為一名 Angular 開發(fā)人員,您可能會發(fā)現(xiàn)以下 RxJS 運(yùn)算符在您的日常開發(fā)中很有用:
01、map():
此運(yùn)算符用于轉(zhuǎn)換可觀察對象發(fā)出的值。它以一個(gè)函數(shù)作為參數(shù),它接收發(fā)出的值作為輸入并返回轉(zhuǎn)換后的輸出。返回的輸出作為可觀察對象的新值發(fā)出。例如,您可以使用 map() 將用戶對象流轉(zhuǎn)換為用戶名流:
import { map } from 'rxjs/operators';
import { UserService } from './user.service';
constructor(private userService: UserService) {}
this.userService.getUsers().pipe(
map(users => users.map(user => user.name))
).subscribe(names => console.log(names));
02、filter():
此運(yùn)算符用于根據(jù)條件過濾掉 observable 發(fā)出的值。它以一個(gè)函數(shù)作為參數(shù),它接收發(fā)出的值作為輸入并返回一個(gè)布爾值。
如果布爾值為 true,則發(fā)出該值,否則將其過濾掉。例如,您可以使用 filter() 只保留整數(shù)流中的偶數(shù):
import { filter } from 'rxjs/operators';
import { of } from 'rxjs';
of(1, 2, 3, 4, 5, 6).pipe(
filter(num => num % 2 === 0)
).subscribe(evenNum => console.log(evenNum));
03、switchMap():
每當(dāng)源可觀察對象發(fā)出新值時(shí),此運(yùn)算符用于切換到新的可觀察對象。它以一個(gè)函數(shù)作為參數(shù),它接收發(fā)出的值作為輸入并返回一個(gè)新的可觀察值。
最新的 observable 發(fā)出的值由返回的 observable 發(fā)出。
例如,您可以使用 switchMap() 根據(jù)另一個(gè)可觀察對象發(fā)出的 ID 獲取用戶數(shù)據(jù):
import { switchMap } from 'rxjs/operators';
import { UserService } from './user.service';
constructor(private userService: UserService) {}
this.userId$.pipe(
switchMap(userId => this.userService.getUser(userId))
).subscribe(user => console.log(user));
04、catchError():
此運(yùn)算符用于處理可觀察對象拋出的錯(cuò)誤。它以一個(gè)函數(shù)作為參數(shù),它接收錯(cuò)誤作為輸入并返回一個(gè)新的可觀察對象。
返回的可觀察對象可以發(fā)出新值、完成或拋出另一個(gè)錯(cuò)誤。例如,您可以使用 catchError() 重試失敗的 HTTP 請求:
import { catchError } from 'rxjs/operators';
import { HttpClient } from '@angular/common/http';
constructor(private http: HttpClient) {}
this.http.get('/api/data').pipe(
catchError(() => this.http.get('/api/fallbackData'))
).subscribe(data => console.log(data));
05、tap():
此運(yùn)算符用于在不修改可觀察對象的發(fā)射值的情況下執(zhí)行副作用。它以一個(gè)函數(shù)作為參數(shù),它接收發(fā)出的值作為輸入并可以執(zhí)行任何副作用。
返回值被忽略,原始值不變。例如,您可以使用 tap() 來記錄可觀察對象發(fā)出的值:
import { tap } from 'rxjs/operators';
import { of } from 'rxjs';
of(1, 2, 3).pipe(
tap(value => console.log(`Emitting value: ${value}`))
).subscribe();
06、take():
此運(yùn)算符用于限制可觀察對象發(fā)出的值的數(shù)量。這是一個(gè)例子:
import { take } from 'rxjs/operators';
import { of } from 'rxjs';
of(1, 2, 3, 4, 5).pipe(
take(3)
).subscribe(value => console.log(value)); // output: 1, 2, 3
在此示例中,take(3) 用于將 of(1, 2, 3, 4, 5) 發(fā)出的數(shù)字流限制為前三個(gè)值。
07、debounceTime():
此運(yùn)算符用于按指定的時(shí)間量對值流進(jìn)行去抖動。這是一個(gè)例子:
import { debounceTime } from 'rxjs/operators';
import { fromEvent } from 'rxjs';
const input = document.getElementById('input');
fromEvent(input, 'input').pipe(
debounceTime(500)
).subscribe(event => console.log(input.value));
在此示例中,debounceTime(500) 用于將來自輸入元素的輸入事件流去抖動 500 毫秒。這意味著如果用戶快速連續(xù)鍵入,則只會記錄 500 毫秒不活動后的輸入值。
08、distinctUntilChanged():
此運(yùn)算符用于僅從值流中發(fā)出不同的值。這是一個(gè)例子:
import { distinctUntilChanged } from 'rxjs/operators';
import { of } from 'rxjs';
of(1, 2, 2, 3, 3, 3, 4).pipe(
distinctUntilChanged()
).subscribe(value => console.log(value)); // output: 1, 2, 3, 4
在此示例中,distinctUntilChanged() 用于僅從 of(1, 2, 2, 3, 3, 3, 4) 發(fā)出的數(shù)字流中發(fā)出不同的值。
09、merge():
此運(yùn)算符用于將多個(gè)可觀察對象合并為一個(gè)可觀察對象。這是一個(gè)例子:
import { merge } from 'rxjs';
import { interval } from 'rxjs';
const obs1 = interval(1000);
const obs2 = interval(2000);
merge(obs1, obs2).subscribe(value => console.log(value));
在此示例中,merge(obs1, obs2) 用于將兩個(gè)可觀察對象 obs1 和 obs2 合并為一個(gè)可觀察對象,該可觀察對象從兩個(gè)可觀察對象發(fā)出值。
10、combineLatest():
該運(yùn)算符將多個(gè)可觀察對象發(fā)出的最新值組合到一個(gè)數(shù)組中。它僅在其中一個(gè)源可觀察對象發(fā)出新值時(shí)發(fā)出新數(shù)組。
import { combineLatest, timer } from 'rxjs';
import { map } from 'rxjs/operators';
const observable1 = timer(0, 1000).pipe(map(x => x + ' seconds'));
const observable2 = timer(500, 500).pipe(map(x => x + ' half seconds'));
combineLatest([observable1, observable2]).subscribe(combinedValues => {
const [value1, value2] = combinedValues;
console.log(`observable1: ${value1}, observable2: ${value2}`);
});
在這個(gè)例子中,我們使用 timer() 函數(shù)創(chuàng)建了兩個(gè)可觀察對象。第一個(gè) observable 每秒發(fā)出一個(gè)值,第二個(gè) observable 每半秒發(fā)出一個(gè)值。我們使用 map() 運(yùn)算符將發(fā)出的值轉(zhuǎn)換為字符串。
然后我們將一組可觀察對象傳遞給 combineLatest() 函數(shù),該函數(shù)返回一個(gè)新的可觀察對象,該可觀察對象發(fā)出一個(gè)包含每個(gè)源可觀察對象發(fā)出的最新值的數(shù)組。我們訂閱這個(gè)新的 observable,并在發(fā)出新的組合值數(shù)組時(shí)記錄每個(gè)源 observable 發(fā)出的值。
這段代碼的輸出看起來像這樣:
observable1: 0 seconds, observable2: 0.5 half seconds
observable1: 1 seconds, observable2: 1 half seconds
observable1: 2 seconds, observable2: 1.5 half seconds
observable1: 3 seconds, observable2: 2 half seconds
observable1: 4 seconds, observable2: 2.5 half seconds
如您所見,只要其中一個(gè)源可觀察對象發(fā)出新值, combineLatest() 運(yùn)算符就會發(fā)出一個(gè)新的組合值數(shù)組。
在這種情況下,第一個(gè) observable 每秒發(fā)出一個(gè)新值,第二個(gè) observable 每半秒發(fā)出一個(gè)新值,因此組合的 observable 每半秒發(fā)出一個(gè)新值。