RxJS Operators: combineLatest() vs forkJoin()
Đặt vấn đề
Giả sử bạn đang phát triển một ứng dụng và cần phải gọi nhiều API cùng một lúc. Bạn phải chờ đến khi tất cả dữ liệu về mới tiếp tục xử lý các bước tiếp theo.
Để tránh callback hell cũng như xử lý cồng kềnh. RxJS cung cấp 2 operators cho tình huống này: forkJoin() và combineLatest()
Cả 2 operators đều là Combination Operators giúp kết hợp nhiều Input Observables thành một Observable duy nhất. Tuy nhiên, nhiều lập trình viên thường nhầm lẫn khi chọn giữa chúng, dẫn đến lỗi không mong muốn hoặc hiệu suất không tối ưu.
Bài viết này sẽ giúp bạn phân biệt rõ ràng sự khác nhau giữa forkJoin
và combineLatest
, cũng như chọn đúng toán tử cho từng trường hợp thực tế.
combineLatest
- Luôn phát giá trị mới nhất
combineLatest() luôn phát ra dữ liệu mỗi khi có một input observable phát dữ liệu.
Cách hoạt động:
- Yêu cầu mỗi Input Observable phải phát ít nhất một giá trị trước khi phát ra kết quả.
- Mỗi khi một trong các Input Observable phát giá trị, nó kết hợp với giá trị mới nhất của các Input Observable khác.
- Không cần chờ tất cả Input Observable hoàn thành.
- Nếu một Input Observable bị lỗi, toàn bộ
combineLatest
sẽ thất bại.
Ví dụ:
import { combineLatest, of, interval } from 'rxjs';
import { take } from 'rxjs/operators';
const obs1 = interval(1000).pipe(take(3)); // Phát 0, 1, 2
const obs2 = of('A', 'B', 'C');
combineLatest([obs1, obs2]).subscribe(
result => console.log(result)
);
// Output có thể là:
// [0, 'A']
// [1, 'A']
// [1, 'B']
// [2, 'B']
// [2, 'C']
Khi nào dùng combineLatest
?
- Khi cần lắng nghe mọi thay đổi từ tất cả Input Observable.
- Khi cần tính toán giá trị mới mỗi khi có sự thay đổi.
forkJoin
- Chỉ phát giá trị cuối cùng của mỗi Observable
forkJoin() chờ đến khi các input observables complete rồi mới phát ra dữ liệu cuối cùng.
Cách hoạt động:
- Chờ tất cả các Input Observable hoàn thành.
- Chỉ lấy giá trị cuối cùng của từng Input Observable.
- Nếu một Input Observable bị lỗi, toàn bộ
forkJoin
sẽ thất bại.
Ví dụ:
import { forkJoin, of } from 'rxjs';
import { delay } from 'rxjs/operators';
const obs1 = of('A').pipe(delay(1000));
const obs2 = of('B').pipe(delay(2000));
const obs3 = of('C').pipe(delay(3000));
forkJoin([obs1, obs2, obs3]).subscribe(
result => console.log(result), // Output: ['A', 'B', 'C'] sau 3 giây
);
Khi nào dùng forkJoin
?
- Khi bạn chỉ quan tâm đến kết quả cuối cùng của từng Input Observable.
- Khi thực hiện các request API song song, nhưng chỉ cần dữ liệu cuối cùng.
So sánh combineLatest
vs forkJoin
Tiêu chí | combineLatest |
forkJoin |
---|---|---|
Cách hoạt động | Mỗi lần có thay đổi từ bất kỳ Input Observable nào, phát giá trị mới nhất | Chờ tất cả hoàn thành và phát giá trị cuối cùng |
Khi nào phát giá trị? | Ngay khi có thay đổi từ ít nhất một Input Observable | Khi tất cả Input Observable hoàn thành |
Xử lý lỗi | Nếu một Input Observable bị lỗi, toàn bộ bị lỗi | Nếu một Input Observable bị lỗi, toàn bộ bị lỗi |
Ứng dụng | Xử lý dữ liệu thời gian thực, cập nhật liên tục | Request API song song, tổng hợp dữ liệu cuối cùng |
Kết luận
- Dùng
combineLatest
khi bạn muốn cập nhật liên tục mỗi khi có dữ liệu mới. - Dùng
forkJoin
khi bạn chỉ cần dữ liệu cuối cùng của tất cả input Observable. - Nếu Input Observable có thể phát lỗi, hãy sử dụng
catchError
để xử lý.
Hy vọng bài viết này giúp bạn hiểu rõ hơn về hai operators mạnh mẽ này!
All rights reserved