Спостерігається нарешті підписка


105

Відповідно до цієї статті , onCompleteа також onErrorфункції subscribeвзаємно виключають один одного.

Значення або onErrorабо onCompleteподії будуть стріляти в моїх subscribe.
У мене є логічний блок, який потрібно виконати, отримавши помилку чи успішно закінчую інформацію.

Я шукав щось на зразок finallypython , але все, що я знайшов - це те, finallyщо потрібно приєднати до створеного нами спостережуваного.

Але я хочу робити цю логіку лише тоді, коли підписуюсь і після закінчення потоку, успішно чи з помилкою.

Якісь ідеї?

Відповіді:


130

Викликається поточний "прототипований" варіант цього оператора finalize()(з RxJS 6). Старіший і тепер застарілий "патч" оператор викликався finally()(до RxJS 5.5).

Я думаю, що finalize()оператор насправді правильний. Ти кажеш:

виконайте цю логіку лише тоді, коли я підпишусь і після закінчення потоку

що я не думаю, що це проблема. Ви можете мати сингл sourceта використовувати finalize()перед тим, як підписатися на нього. Таким чином, від вас не завжди потрібно використовувати 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();

Це друк для консолі:

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

Січень 2019 року: оновлено для RxJS 6


1
Цікаво, що це свого роду протилежна закономірність Обіцянь, оскільки finally()метод додається спочатку, а підписка в обов'язковому порядку примушує проходити / провалюватися.
BradGreens

7
Так, це дуже погано. Можна було б подумати, що finallyблок буде останнім у вашому коді.
d512

Мені сподобалась система обіцянок Angular JS ... Як говорить d512, я очікував, що "нарешті" буде останнім ... Мені це зовсім не подобається ...
Сампгун

10
За станом на RXJS 5.5, "нарешті" - це вже не метод спостереження. Замість цього скористайтеся оператором "finalize": source.pipe (finalize (() => console.log ('Нарешті зворотний виклик'))). Підписатися (...); github.com/ReactiveX/rxjs/blob/master/doc/pipeable-operators.md
Stevethemacguy

проблема з завершенням - це очікування виклику "завершення ()". що робити, якщо ви хочете, нарешті, для кожного викиду (якщо спостережувана емісія є успішною, зробіть a , якщо вона помиляється, зробіть b замість цього .. в обох випадках зробіть c )?
roberto tomás

65

Єдине, що для мене працювало, це це

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

26

Зараз я використовую RxJS 5.5.7 в кутовій програмі, а finalizeоператор використовує дивну поведінку в моєму випадку використання, оскільки він запускається перед відмовою від успіху чи помилки.

Простий приклад:

// 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);
      }
  );

Мені довелося користуватися addмедходом у підписці, щоб досягти того, що я хочу. В основному finallyзворотний виклик після відкликання успіху чи помилки робиться. Як try..catch..finallyблок або Promise.finallyметод.

Простий приклад:

// 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.');
  });

Радий допомогти вам.
pcasme
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.