Skip to content

RxJS 簡介

RxJS 是一種用於處理異步資料流和事件的函式式編程庫。它基於 反應式編程 概念,這是一種專注於數據流和變化傳播的編程範式。

Observables & Observers

  • Observables: 是一系列的資料流或事件的集合。它們可以發出三種類型的值:一般的值、錯誤或一個完成的信號。
  • Observers: 是一個接收 Observable 發出的值的集合體,可視為 Observables 的消費者。

import { Observable } from 'rxjs';

const observable = new Observable(subscriber => {
  subscriber.next(1); // 發出值 1
  subscriber.next(2); // 然後是 2
  subscriber.next(3); // 接著是 3
  setTimeout(() => {
    subscriber.next(4); // 1秒後發出 4
    subscriber.complete(); // 完成 Observable
  }, 1000);
});

observable.subscribe({
  next(x) { console.log('got value ' + x); }, // 每當有值發出時,會呼叫此函式
  error(err) { console.error('something wrong occurred: ' + err); }, // 錯誤處理
  complete() { console.log('done'); } // 完成時呼叫
});
這個範例中,Observable 發出四個值,並在最後標記為完成。每當 Observable 發出一個值,訂閱它的觀察者的 next 方法就會被呼叫。

常用 RxJS 操作符

操作符是 RxJS 的核心,用於處理、轉換、組合和創建 Observables。例如 map(), filter(), concat(), merge() 等。

import { of } from 'rxjs';
import { map } from 'rxjs/operators';

of(1, 2, 3)
  .pipe(map(x => x * x))
  .subscribe(x => console.log(x));
在這個範例中,of 函數創建一個發出三個數字(1, 2, 3)的 Observable,map 操作符將每個值映射成其平方,然後這些平方值被發出。

RxJS 處理事件與異步資料流實作

RxJS 提供了強大的工具集來處理異步事件和資料流。

import { fromEvent } from 'rxjs';

const button = document.querySelector('button');
fromEvent(button, 'click')
  .subscribe(() => console.log('Clicked!'));
此範例中,fromEvent 函數創建了一個 Observable,它監聽指定元素(這裡是一個按鈕)上的點擊事件。每當按鈕被點擊時,就會發出一個事件,觀察者接收到這個事件並執行相應的操作(在這裡是輸出 'Clicked!')。

進階 Observables 操作

進階 Observables 是 Observables 的值本身也是 Observables。常見的操作有 mergeMap(), switchMap() 等。

import { of } from 'rxjs';
import { mergeMap } from 'rxjs/operators';

of('Hello')
  .pipe(mergeMap(x => of(x + ' World')))
  .subscribe(x => console.log(x));
這裡,mergeMap 操作符用於將一

個 Observable(發出 'Hello')的值映射為另一個 Observable(發出 'Hello World'),然後合併這些 Observable 的輸出。

RxJS 錯誤處理

錯誤處理是任何編程語言中的重要部分。RxJS 提供 catchErrorretry 等操作符來處理錯誤。

import { of } from 'rxjs';
import { catchError } from 'rxjs/operators';

of(1, 2, 3, 4, 5)
  .pipe(
    map(x => {
      if (x === 3) {
        throw new Error('Three is not allowed');
      }
      return x;
    }),
    catchError(err => of('I', 'II', 'III'))
  )
  .subscribe(x => console.log(x));
在這個範例中,當 Observable 發出值 3 時,會拋出一個錯誤。catchError 操作符捕捉這個錯誤,並返回一個新的 Observable,該 Observable 發出三個不同的值。

RxJS 於 Angular 服務和組件應用

在 Angular 中,RxJS 被廣泛用於處理 HTTP 請求、事件處理和狀態管理。

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class DataService {
  constructor(private http: HttpClient) {}

  getData(): Observable<any> {
    return this.http.get('https://api.example.com/data');
  }
}
在這個 Angular 服務範例中,使用 RxJS 的 Observable 來處理 HTTP 請求。getData 方法使用 HttpClientget 方法來發出 HTTP 請求,並返回一個 Observable,該 Observable 在請求完成時發出響應。

實作 Angular 響應式表單

Angular 響應式表單提供了一種使用 RxJS 來處理表單輸入和驗證的方式。

import { Component } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';

@Component({
  selector: 'app-example-form',
  template: `
    <form [formGroup]="exampleForm">
      <input formControlName="exampleControl" />
    </form>
  `
})
export class ExampleFormComponent {
  exampleForm = new FormGroup({
    exampleControl: new FormControl('')
  });
}
在這個 Angular 組件範例中,使用 FormGroupFormControl 來建立響應式表單。FormGroup 表示表單本身,而 FormControl 則代表表單中的單個控制項。這些控制項與 HTML 模板中的對應元素綁定,使得表單的狀態和用戶界面能夠實時同步。