Giới thiệu cơ bản về Observable (dành cho Angular hoặc RxJS)
Trong lập trình bất đồng bộ, Observable là một khái niệm quan trọng và mạnh mẽ, đặc biệt trong các ứng dụng Angular và khi sử dụng thư viện RxJS. Observable cung cấp một cách thức xử lý dữ liệu bất đồng bộ như là một dòng dữ liệu (stream) mà có thể phát sinh nhiều giá trị theo thời gian.

Bài viết này sẽ cung cấp cái nhìn tổng quan về Observable, cách thức hoạt động và cách sử dụng nó trong Angular hoặc RxJS.
1. Observable là gì?
Observable là một đối tượng trong lập trình bất đồng bộ có thể phát ra nhiều giá trị trong suốt thời gian sống của nó. Observable là một phần của thư viện RxJS (Reactive Extensions for JavaScript) và được sử dụng phổ biến trong các ứng dụng Angular để xử lý các tác vụ bất đồng bộ như gọi API, sự kiện người dùng, và các tác vụ liên tục.
1.1. Các thành phần trong Observable
-
Observer: Là đối tượng nhận các giá trị do Observable phát ra. Observer có 3 phương thức chính:
- next(): Được gọi mỗi khi có giá trị mới phát sinh.
- error(): Được gọi khi xảy ra lỗi.
- complete(): Được gọi khi Observable hoàn thành và không phát sinh thêm giá trị.
-
Subscription: Là đối tượng đại diện cho kết nối giữa Observable và Observer. Khi bạn subscribe (đăng ký) vào Observable, bạn sẽ nhận được các giá trị do Observable phát sinh.
-
Operators: Là các phương thức mà bạn có thể sử dụng để biến đổi hoặc kết hợp các Observable. Ví dụ:
map()
,filter()
,merge()
,concat()
, v.v.
1.2. Cách thức hoạt động của Observable
Khi bạn gọi observable.subscribe()
, Observable sẽ bắt đầu phát các giá trị cho Observer. Một Observable có thể phát ra nhiều giá trị hoặc chỉ phát ra một giá trị duy nhất, hoặc có thể phát sinh một lỗi.
2. Sử dụng Observable trong RxJS
RxJS là một thư viện JavaScript cung cấp các công cụ để làm việc với Observable. Dưới đây là cách tạo và sử dụng Observable trong RxJS.
2.1. Tạo Observable
Để tạo một Observable trong RxJS, bạn sử dụng Observable.create()
hoặc new Observable()
.
import { Observable } from 'rxjs';
// Tạo Observable đơn giản
const observable = new Observable(subscriber => {
subscriber.next(1); // Phát ra giá trị 1
subscriber.next(2); // Phát ra giá trị 2
subscriber.next(3); // Phát ra giá trị 3
subscriber.complete(); // Hoàn thành Observable
});
2.2. Subscribe vào Observable
Sau khi tạo Observable, bạn có thể đăng ký (subscribe) vào nó để nhận giá trị.
observable.subscribe({
next(x) { console.log('Received: ' + x); },
complete() { console.log('Completed!'); }
});
Output:
Received: 1
Received: 2
Received: 3
Completed!
2.3. Sử dụng các Operator trong Observable
RxJS cung cấp một loạt các operator để xử lý dữ liệu trong Observable. Một số operator thông dụng là map()
, filter()
, mergeMap()
, và debounceTime()
.
import { of } from 'rxjs';
import { map, filter } from 'rxjs/operators';
// Sử dụng operator map và filter để biến đổi dữ liệu
const observable = of(1, 2, 3, 4, 5).pipe(
filter(x => x % 2 === 0), // Chỉ lấy các số chẵn
map(x => x * 2) // Nhân đôi giá trị
);
observable.subscribe(x => console.log(x));
Output:
4
8
Trong ví dụ trên:
-
filter()
chỉ cho phép giá trị chẵn đi qua. -
map()
nhân đôi các giá trị đã được lọc.
3. Observable trong Angular
Trong Angular, Observable là thành phần chủ chốt để làm việc với các tác vụ bất đồng bộ, đặc biệt là khi gọi API hoặc xử lý các sự kiện như nhập liệu, hoặc thay đổi trạng thái. Angular tích hợp RxJS sẵn để sử dụng với các dịch vụ như HttpClient, Forms, Router và các công cụ khác.
3.1. Observable với HttpClient trong Angular
Angular cung cấp HttpClient để gọi API và trả về Observable. Bạn có thể sử dụng Observable trong các dịch vụ của Angular để xử lý dữ liệu từ API.
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');
}
}
3.2. Subscription trong Component
Trong Component của Angular, bạn có thể subscribe vào Observable và nhận kết quả trả về từ API.
import { Component, OnInit } from '@angular/core';
import { DataService } from './data.service';
@Component({
selector: 'app-my-component',
templateUrl: './my-component.component.html'
})
export class MyComponent implements OnInit {
data: any;
constructor(private dataService: DataService) {}
ngOnInit() {
this.dataService.getData().subscribe(data => {
this.data = data;
console.log(this.data); // Xử lý dữ liệu trả về từ API
});
}
}
4. Kết luận
Observable là một khái niệm quan trọng trong lập trình bất đồng bộ, đặc biệt khi sử dụng RxJS trong Angular. Observable cung cấp một cách tiếp cận rất mạnh mẽ để xử lý dữ liệu theo dòng thời gian, đồng thời cung cấp các tính năng như kết hợp các dòng dữ liệu, xử lý lỗi, và sự kiện bất đồng bộ trong ứng dụng.
Nếu bạn làm việc với Angular hoặc bất kỳ ứng dụng JavaScript nào cần xử lý bất đồng bộ, việc sử dụng Observable sẽ giúp mã của bạn trở nên dễ bảo trì và dễ kiểm soát hơn.
Với RxJS, bạn có thể sử dụng các operator để làm việc với Observable và biến đổi, kết hợp chúng một cách linh hoạt và mạnh mẽ.

Với hơn 10 năm kinh nghiệm lập trình web và từng làm việc với nhiều framework, ngôn ngữ như PHP, JavaScript, React, jQuery, CSS, HTML, CakePHP, Laravel..., tôi hy vọng những kiến thức được chia sẻ tại đây sẽ hữu ích và thiết thực cho các bạn.
Xem thêm

Chào, tôi là Vũ. Đây là blog hướng dẫn lập trình của tôi.
Liên hệ công việc qua email dưới đây.
lhvuctu@gmail.com