乐闻世界logo
搜索文章和话题

What are the common operators in RxJS and how to use them?

2月21日 16:28

Common Operator Categories

1. Creation Operators

of

Creates an Observable that emits specified values

javascript
import { of } from 'rxjs'; of(1, 2, 3).subscribe(console.log); // Output: 1, 2, 3

from

Converts arrays, Promises, Iterables, etc. to Observable

javascript
import { from } from 'rxjs'; from([1, 2, 3]).subscribe(console.log); // Output: 1, 2, 3 from(Promise.resolve('Hello')).subscribe(console.log); // Output: Hello

interval / timer

Creates Observables that emit at regular intervals

javascript
import { interval, timer } from 'rxjs'; interval(1000).subscribe(console.log); // Emits an incrementing number every second: 0, 1, 2, 3... timer(2000, 1000).subscribe(console.log); // Starts after 2 seconds, emits a number every second: 0, 1, 2, 3...

2. Transformation Operators

map

Transforms each emitted value

javascript
import { of } from 'rxjs'; import { map } from 'rxjs/operators'; of(1, 2, 3).pipe( map(x => x * 2) ).subscribe(console.log); // Output: 2, 4, 6

switchMap

Cancels previous inner Observable, only handles the latest one

javascript
import { fromEvent } from 'rxjs'; import { switchMap } from 'rxjs/operators'; fromEvent(document, 'click').pipe( switchMap(() => fetch('/api/data')) ).subscribe(response => console.log(response));

mergeMap

Processes all inner Observables in parallel

javascript
import { of } from 'rxjs'; import { mergeMap } from 'rxjs/operators'; of(1, 2, 3).pipe( mergeMap(x => of(x, x * 2)) ).subscribe(console.log); // Output: 1, 2, 2, 4, 3, 6

concatMap

Processes inner Observables sequentially, one after another

javascript
import { of } from 'rxjs'; import { concatMap } from 'rxjs/operators'; of(1, 2, 3).pipe( concatMap(x => of(x, x * 2)) ).subscribe(console.log); // Output: 1, 2, 2, 4, 3, 6 (sequential execution)

3. Filtering Operators

filter

Filters values that meet the condition

javascript
import { of } from 'rxjs'; import { filter } from 'rxjs/operators'; of(1, 2, 3, 4, 5).pipe( filter(x => x % 2 === 0) ).subscribe(console.log); // Output: 2, 4

take / takeLast / takeUntil

Takes the first few, last few, or until a condition

javascript
import { interval, fromEvent } from 'rxjs'; import { take, takeUntil } from 'rxjs/operators'; interval(1000).pipe( take(3) ).subscribe(console.log); // Output: 0, 1, 2 interval(1000).pipe( takeUntil(fromEvent(document, 'click')) ).subscribe(console.log); // Stops when clicked

debounceTime

Emits only the last value within a specified time

javascript
import { fromEvent } from 'rxjs'; import { debounceTime } from 'rxjs/operators'; fromEvent(inputElement, 'input').pipe( debounceTime(300) ).subscribe(event => console.log(event.target.value));

throttleTime

Emits only the first value within a specified time

javascript
import { fromEvent } from 'rxjs'; import { throttleTime } from 'rxjs/operators'; fromEvent(window, 'scroll').pipe( throttleTime(200) ).subscribe(event => console.log('Scroll event'));

4. Combination Operators

merge

Merges multiple Observables, emits values in parallel

javascript
import { merge, interval } from 'rxjs'; merge( interval(1000).pipe(map(x => `A${x}`)), interval(1500).pipe(map(x => `B${x}`)) ).subscribe(console.log);

concat

Sequentially connects multiple Observables

javascript
import { concat, of } from 'rxjs'; concat( of(1, 2), of(3, 4), of(5, 6) ).subscribe(console.log); // Output: 1, 2, 3, 4, 5, 6

combineLatest

Combines the latest values from multiple Observables

javascript
import { combineLatest, of } from 'rxjs'; combineLatest([ of(1, 2, 3), of('a', 'b', 'c') ]).subscribe(([num, char]) => console.log(num, char)); // Output: [3, 'a'], [3, 'b'], [3, 'c']

zip

Combines values from multiple Observables by index

javascript
import { zip, of } from 'rxjs'; zip( of(1, 2, 3), of('a', 'b', 'c') ).subscribe(([num, char]) => console.log(num, char)); // Output: [1, 'a'], [2, 'b'], [3, 'c']

5. Error Handling Operators

catchError

Catches errors and returns a new Observable

javascript
import { of } from 'rxjs'; import { map, catchError } from 'rxjs/operators'; of(1, 2, 3, 4).pipe( map(x => { if (x === 3) throw new Error('Error!'); return x; }), catchError(error => of('default value')) ).subscribe(console.log); // Output: 1, 2, 'default value'

retry

Retries failed Observables

javascript
import { of } from 'rxjs'; import { map, retry } from 'rxjs/operators'; let count = 0; of(1, 2, 3).pipe( map(x => { count++; if (count < 3) throw new Error('Error!'); return x; }), retry(2) ).subscribe(console.log);

6. Utility Operators

tap

Executes side effects without modifying values

javascript
import { of } from 'rxjs'; import { tap, map } from 'rxjs/operators'; of(1, 2, 3).pipe( tap(x => console.log('Before:', x)), map(x => x * 2), tap(x => console.log('After:', x)) ).subscribe();

delay

Delays emission of values

javascript
import { of } from 'rxjs'; import { delay } from 'rxjs/operators'; of(1, 2, 3).pipe( delay(1000) ).subscribe(console.log); // Output after 1 second: 1, 2, 3

Practical Application Examples

javascript
fromEvent(searchInput, 'input').pipe( debounceTime(300), map(event => event.target.value), filter(query => query.length > 2), switchMap(query => searchAPI(query)) ).subscribe(results => displayResults(results));

Auto-save

javascript
form.valueChanges.pipe( debounceTime(1000), distinctUntilChanged(), switchMap(formData => saveAPI(formData)) ).subscribe();

Parallel Requests

javascript
merge( getUserData(userId), getUserPosts(userId), getUserComments(userId) ).pipe( combineLatestAll() ).subscribe(([user, posts, comments]) => { renderUserProfile(user, posts, comments); });

Best Practices

  1. Reasonably use pipe() for chaining
  2. Pay attention to operator execution order
  3. Unsubscribe in time to avoid memory leaks
  4. Choose appropriate operators based on the scenario
  5. Use TypeScript for better type inference
标签:Rxjs