RxJS вложенная подписка - PullRequest
1 голос
/ 04 апреля 2019

Можно ли избежать вложенной подписки в следующем коде?

this.requestService().subscribe(
      () => this.success(),
      error => {
        const errorDescription = {
          one: 5,
          two: 10
        };
        return this.error(errorDescription).subscribe();
      }
    );

Второй subscribe является частью обратного вызова ошибки Наблюдателя,Как мы можем использовать, например, switchMap, чтобы иметь только одну подписку?

Ответы [ 3 ]

2 голосов
/ 05 апреля 2019

Похоже, вам нужен catchError, который позволит вам заменить ошибку другим потоком.Хотя нам придется обновить успешную обработку результатов:

this.requestService().pipe(

  // handle success value
  tap(() => this.success()),

  // when an error happens
  catchError(error => {
    const errorDescription = {
      one: 5,
      two: 10
    };

    // we switch to `this.error` stream
    return this.error(errorDescription);
  })
).subscribe(value=>{
  // ...here you'll receive both:
  // events from the requestService()
  // and events from this.error(errorDescription)
});

Вот статья с подробным обзором обработки ошибок в RxJS

Надеюсь, это поможет

0 голосов
/ 05 апреля 2019

Я бы, наверное, сделал это так:

this.requestService().pipe(catchError(e => {
  const errorDescription = {
      one: 5,
      two: 10
  };
  return this.error(errorDescription).pipe(switchMap(empty())); 
  // the switch to empty will prevent the error going to success
  // consider moving this into the error handler itself.
})).subscribe(
  () => this.success(),
  error => {
    //should never get here.
  }
);

catchError -> switchMap -> empty - это шаблон, который довольно часто встречается в моем коде, так как мои обработчики ошибок должны чаще останавливать цепочку обработки.

0 голосов
/ 05 апреля 2019

Вот идея избежать «вложенной» подписки. С предоставленным вами кодом, это лучшее, что я могу придумать. Если у вас есть какие-либо вопросы, дайте мне знать, и я помогу.

import { of, throwError } from 'rxjs'; 
import { map, switchMap, catchError } from 'rxjs/operators';


// this.requestService().subscribe(
//       () => this.success(),
//       error => {
//         const errorDescription = {
//           one: 5,
//           two: 10
//         };
//         return this.error(errorDescription).subscribe();
//       }
//     );

const error = throwError('oops');
const success = of('success!');
const handleError = (d) => of({one: 5, two: 10}).pipe(
  map(n => n),
  catchError(e => 'could not do 2nd network request')
);

const requestServiceSuccess = success.pipe(
  switchMap(d => of(d)),
  catchError(handleError)
)

const requestServiceFail = error.pipe(
  switchMap(d => of(d)),
  catchError(handleError)
)

// if your first network request succeeds, then you will see success
requestServiceSuccess.subscribe(
  (d) => console.log(d),
  (e) => console.log(e)
)
// if your first network request fails, then you will see your errorDescription
requestServiceFail.subscribe(
  (d) => console.log(d),
  (e) => console.log(e)
)

Вы можете вставить это в stackblitz, чтобы проверить журналы

https://stackblitz.com/fork/rxjs?devtoolsheight=60

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...