+1

RxJS Operators: combineLatest() vs forkJoin()

RxJS forkJoin vs combineLatest

Đặ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()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 forkJoincombineLatest , 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.

RxJS forkJoin vs combineLatest

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.

RxJS forkJoin vs combineLatest

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

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí