Каков наилучший способ отмены и обработки ошибок в RX JS v6 - PullRequest
1 голос
/ 24 апреля 2020
import { fromEvent, interval, Subject, Observable, of } from "rxjs";
import { takeUntil, switchMap, catchError } from "rxjs/operators";

const obs1 = p1 => {
  return new Observable(observer => {
    setTimeout(() => {
      console.log("obs1 doing");
      observer.next(p1 + "1");
      observer.complete();
    }, 1000);
  });
};
const obs2 = p2 => {
  return new Observable(observer => {
    setTimeout(() => {
      console.log("obs2 doing");
      observer.next(p2 + "2");
      observer.complete();
    }, 1000);
  });
};
const obs3 = p3 => {
  return new Observable(observer => {
    setTimeout(() => {
      console.log("obs3 doing");
      observer.next(p3 + "3");
      observer.complete();
    }, 1000);
  });
};
const obsError1 = () => console.log("obs1 is error")
const obsError2 = () => console.log("obs2 is  error")
const obsError3 = () => console.log("obs3 is error")
const cancle = new Subject();

new Observable(observer => {
  obs1(0).subscribe(
    x1 => {
      obs2(x1).subscribe(
        x2 => {
          obs3(x2).subscribe(
            x3 => {
              observer.next(x3);
              observer.complete();
            },
            obsError3
          );
        },
        obsError2
      );
    },
    obsError1
  );
}).pipe(takeUntil(cancle)).subscribe(()=>{
  console.log()
});

setTimeout(() => {
  console.log("cancle doing");
  cancle.next();
  cancle.complete();
}, 100);

Когда он запускается cancle.next(), он по-прежнему печатает obs2 doing и obs3 doing

Я знаю, что переход на серийный номер можно отменить, например:

setTimeout(() => {
  console.log("cancle doing");
  cancle.next();
  cancle.complete();
}, 100);

of(0)
  .pipe(
    switchMap(x1 => obs1(x1)),
    catchError(error => {
      obsError1()
      throw error;
    })
  ).pipe(
    switchMap(x2 => obs2(x2)),
    catchError(error => {
      obsError2()
      throw error;
    })
  )
  .pipe(
    switchMap(x3 => obs3(x3)),
    catchError(error => {
      obsError3()
      throw error;
    })
  ).pipe(
    takeUntil(cancle)
  ).subscribe(x => {
  console.log(x);
});

Но когда возникает ошибка в obs1, obsError2 также будет выполняться

Я не знаю лучший способ обработки ошибок

весь код находится в https://stackblitz.com/edit/mbqhrs

1 Ответ

0 голосов
/ 24 апреля 2020

Если вы хотите обработать ошибку в потоке, вам нужно использовать оператор catchError. Он принимает ошибку, если вы можете ее обработать - просто верните новый поток, если ошибка должна быть передана дальше - просто выбросьте ее снова.

o$.pipe(
 catchError(error => {
   if (error.message === 'i can handle it') {
      return of('value we want to pass');
   }
   if (error.message === 'i can handle it 2') {
      return EMPTY; // simply completes the stream without an emit.
   }
   throw error; // i don't know what to do with such an error.
 }),
).subscribe(console.log); // can receive 'i can handle it'.
...