Chỉ cần tự hỏi sự khác biệt giữa Observable.combineLatest
và là Observable.forkJoin
gì? Theo như tôi thấy, sự khác biệt duy nhất là forkJoin
mong đợi các Observables được hoàn thành, trong khi combineLatest
trả về các giá trị mới nhất.
Câu trả lời:
Không chỉ forkJoin
yêu cầu hoàn thành tất cả các quan sát đầu vào mà còn trả về một có thể quan sát tạo ra một giá trị duy nhất là mảng các giá trị cuối cùng được tạo ra bởi các quan sát đầu vào. Nói cách khác, nó đợi cho đến khi đầu vào cuối cùng có thể quan sát được hoàn thành, sau đó tạo ra một giá trị duy nhất và hoàn thành.
Ngược lại, combineLatest
trả về một Quan sát được tạo ra một giá trị mới mỗi khi các quan sát đầu vào thực hiện, khi tất cả các quan sát đầu vào đã tạo ra ít nhất một giá trị. Điều này có nghĩa là nó có thể có giá trị vô hạn và có thể không hoàn thành. Điều đó cũng có nghĩa là các dữ liệu quan sát đầu vào không cần phải hoàn thành trước khi tạo ra một giá trị.
.catch()
, .onErrorResumeNext()
và có thể .retry()
(nếu cuộc gọi Http có thể thất bại liên tục).
combineLatest()
, bạn có thể cung cấp một hàm chiếu để chỉ định cách tạo ra giá trị đầu ra từ các giá trị mới nhất từ các vật quan sát đầu vào. Theo mặc định, nếu bạn không chỉ định một, bạn sẽ nhận được một mảng các giá trị mới nhất được phát ra.
Cũng thế:
combineLatest
sử dụng nội bộ concat
, có nghĩa là một giá trị phải được lấy cho mỗi có thể quan sát trong mảng trước khi chuyển sang phần tiếp theo.
// partial source of static combineLatest (uses the rxjs/operators combineLatest internally):
// If you're using typescript then the output array will be strongly typed based on type inference
return function (source) { return source.lift.call(from_1.from([source].concat(observables)),
new combineLatest_1.CombineLatestOperator(project)); };
Nếu bạn có 3 nguồn quan sát và mỗi nguồn mất 5 giây để chạy thì sẽ mất 15 giây combineLatest
để chạy. Trong khi forkJoin
chúng thực hiện song song nên sẽ mất 5 giây.
Vì vậy, forkJoin
hoạt động giống như Promise.all(...)
nơi lệnh không được thực thi.
Nếu bất kỳ lỗi nào có thể quan sát được - với combineLatest
những lỗi tiếp theo sẽ không được thực thi, nhưng forkJoin
tất cả chúng đều đang chạy. Vì vậy, combineLatest
có thể hữu ích để thực hiện một 'chuỗi' các vật thể quan sát và thu thập tất cả kết quả cùng nhau.
Lưu ý nâng cao: Nếu các nguồn có thể quan sát đã 'đang chạy' (được đăng ký bởi thứ khác) và bạn đang sử dụng share
chúng - thì bạn sẽ không thấy hành vi này.
Lưu ý nâng cao hơn nữa: CombineLatest sẽ luôn cung cấp cho bạn thông tin mới nhất từ mỗi nguồn, vì vậy nếu một trong các nguồn có thể quan sát phát ra nhiều giá trị, bạn sẽ nhận được giá trị mới nhất. Nó không chỉ nhận một giá trị duy nhất cho mỗi nguồn và chuyển sang nguồn tiếp theo. Nếu bạn cần đảm bảo rằng bạn chỉ nhận được 'mục có sẵn tiếp theo' cho mỗi nguồn có thể quan sát được, bạn có thể thêm .pipe(take(1))
vào nguồn có thể quan sát khi bạn thêm nó vào mảng đầu vào.
concat()
trong combineLatest()
mã đang làm. Đối với tôi, nó giống như Array.prototype.concat
phương pháp, không phải concat
phương pháp RxJS . Giả sử tôi đúng, thì câu trả lời này gây hiểu lầm và không chính xác, vì combineLatest()
không thực thi từng cái một, theo trình tự. Nó thực hiện chúng song song, giống như forkJoin()
. Sự khác biệt là có bao nhiêu giá trị được tạo ra và liệu các nguồn quan sát có phải hoàn thành hay không.
[source].concat(observables)
:, giả sử đó là ý của bạn khi nói rằng " combineLatest
sử dụng nội bộ concat
". Đối với tôi, có vẻ như bạn đang nhầm lẫn giữa kết hợp mảng với RxJS concat. Cái thứ hai thực sự thực thi các quan sát đầu vào theo trình tự, đợi cho đến khi hoàn thành mỗi cái. Nhưng điều đó không được sử dụng bởi combineLatest()
, đó là một toán tử riêng biệt hoàn toàn.
combineLatest()
và forkJoin()
cả hai đều chạy song song. Chạy đoạn mã dưới đây cho ra khoảng 5000 cho cả hai. const start = new Date().getTime();
combineLatest([of(null).pipe(delay(5000)), of(null).pipe(delay(5000)), of(null).pipe(delay(5000))]).subscribe(() => console.log(new Date().getTime() - start));
forkJoin([of(null).pipe(delay(5000)), of(null).pipe(delay(5000)), of(null).pipe(delay(5000))]).subscribe(() => console.log(new Date().getTime() - start));
forkJoin - Khi tất cả các khả năng quan sát hoàn thành, hãy phát ra giá trị phát ra cuối cùng từ mỗi.
connectLatest - Khi bất kỳ giá trị nào có thể quan sát được phát ra một giá trị, hãy phát ra giá trị mới nhất từ mỗi giá trị.
Cách sử dụng khá giống nhau, nhưng bạn không nên quên hủy đăng ký kết hợp với forkJoin .
combineLatest()
vàforkJoin()
chức năng mà tạo ra một quan sát được. Họ làm giống nhau, nhưng cú pháp khác nhau. Đừng nhầm lẫncombineLatest
từrxjs/operators
đó là toán tử 'có thể phân phối'. Nếu bạn nhập sai, bạn sẽ gặp lỗi.