Có thể quan sát được cuối cùng trên Đăng ký


105

Theo artcle này , onCompleteonErrorchức năng của subscribechúng loại trừ lẫn nhau.

Có nghĩa là một trong hai onErrorhoặc onCompletecác sự kiện sẽ bùng lên trong tôi subscribe.
Tôi có một khối logic cần được thực thi cho dù tôi nhận được lỗi hoặc tôi hoàn thành thông tin thành công.

Tôi đã tìm kiếm một cái gì đó giống như finallytrong python , nhưng tất cả những gì tôi tìm thấy là finallycái cần được gắn vào cái mà tôi có thể quan sát được.

Nhưng tôi chỉ muốn thực hiện logic đó khi đăng ký và sau khi luồng kết thúc, dù thành công hay có lỗi.

Bất kỳ ý tưởng?

Câu trả lời:


130

Biến thể "có thể chuyển đổi" hiện tại của toán tử này được gọi finalize()(kể từ RxJS 6). Toán tử "bản vá" cũ hơn và hiện không được dùng nữa đã được gọi finally()(cho đến RxJS 5.5).

Tôi nghĩ rằng finalize()nhà điều hành thực sự là chính xác. Bạn nói:

thực hiện logic đó chỉ khi tôi đăng ký và sau khi luồng kết thúc

đó không phải là một vấn đề tôi nghĩ. Bạn có thể có một cái duy nhất sourcevà sử dụng finalize()trước khi đăng ký nó nếu bạn muốn. Bằng cách này, bạn không bắt buộc phải luôn sử dụng finalize():

let source = new Observable(observer => {
  observer.next(1);
  observer.error('error message');
  observer.next(3);
  observer.complete();
}).pipe(
  publish(),
);

source.pipe(
  finalize(() => console.log('Finally callback')),
).subscribe(
  value => console.log('#1 Next:', value),
  error => console.log('#1 Error:', error),
  () => console.log('#1 Complete')
);

source.subscribe(
  value => console.log('#2 Next:', value),
  error => console.log('#2 Error:', error),
  () => console.log('#2 Complete')
);

source.connect();

Điều này in ra bảng điều khiển:

#1 Next: 1
#2 Next: 1
#1 Error: error message
Finally callback
#2 Error: error message

Tháng 1 năm 2019: Cập nhật cho RxJS 6


1
Điều thú vị là nó giống như một mô hình ngược lại với Promises, trong đó finally()phương thức được nối trước và việc đăng ký bắt buộc phải đạt / không thành công.
BradGreens,

7
Ừ, tệ quá. Người ta sẽ nghĩ rằng finallykhối sẽ xuất hiện cuối cùng trong mã của bạn.
d512

Tôi thích hệ thống lời hứa của Angular JS ... Như d512 nói tôi mong đợi "cuối cùng" là người cuối cùng ... Đừng như thế này ở tất cả các ...
Sampgun

10
Kể từ RXJS 5.5, "cuối cùng" không còn là một phương pháp có thể quan sát được nữa. Thay vào đó, hãy sử dụng toán tử "finalize": source.pipe (finalize (() => console.log ('Cuối cùng gọi lại'))). Subscribe (...); github.com/ReactiveX/rxjs/blob/master/doc/pipable-operators.md
Stevethemacguy

vấn đề với finalize là nó đang đợi lệnh gọi "complete ()". Điều gì sẽ xảy ra nếu bạn muốn một cuối cùng trên mỗi phát xạ (nếu phát xạ quan sát được thành công, hãy làm a , nếu nó sai, hãy làm thay thế b .. trong cả hai trường hợp, hãy làm c )?
roberto tomás

65

Điều duy nhất làm việc cho tôi là cái này

fetchData()
  .subscribe(
    (data) => {
       //Called when success
     },
    (error) => {
       //Called when error
    }
  ).add(() => {
       //Called when operation is complete (both success and error)
  });

26

Tôi hiện đang sử dụng RxJS 5.5.7 trong một ứng dụng Angular và finalizetoán tử sử dụng có một hành vi kỳ lạ đối với trường hợp sử dụng của tôi vì nó được kích hoạt trước khi gọi lại thành công hoặc lỗi.

Ví dụ đơn giản:

// Simulate an AJAX callback...
of(null)
  .pipe(
    delay(2000),
    finalize(() => {
      // Do some work after complete...
      console.log('Finalize method executed before "Data available" (or error thrown)');
    })
  )
  .subscribe(
      response => {
        console.log('Data available.');
      },
      err => {
        console.error(err);
      }
  );

Tôi đã phải sử dụng addmedhod trong đăng ký để đạt được những gì tôi muốn. Về cơ bản là một finallycuộc gọi lại sau khi các cuộc gọi lại thành công hoặc lỗi được thực hiện. Giống như một try..catch..finallykhối hoặc Promise.finallyphương thức.

Ví dụ đơn giản:

// Simulate an AJAX callback...
of(null)
  .pipe(
    delay(2000)
  )
  .subscribe(
      response => {
        console.log('Data available.');
      },
      err => {
        console.error(err);
      }
  );
  .add(() => {
    // Do some work after complete...
    console.log('At this point the success or error callbacks has been completed.');
  });

Rất vui được giúp bạn.
pcasme
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.