RxJS 如何出错后不自动取消订阅?

发布于 2022-09-12 03:07:12 字数 1441 浏览 17 评论 0

假设有如下代码模拟我目前的环境,
在线查看地址:https://stackblitz.com/edit/r...

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

/**
 * 模拟通过http请求获取数据
 */
function getData(value) {
  return of(value)
    .pipe(map(value => {
      // 模拟http请求报错
      if(value % 2 === 0) {
        throw new Error('不是奇数');
      }
      return value;
    }));
}

const subject = new BehaviorSubject<number>(1);

subject
  .pipe(switchMap(value => {
    return getData(value);
  }))
  .pipe(tap(value => console.log(value)))
  .pipe(catchError(err => {
    console.error(err);
    return of(null);
  }))
  .subscribe();

for(let i of [3 ,5 ,7 ,9 ,10, 11, 13, 15, 17]) {
  subject.next(i);
}

上面的代码在运行的时候输出如下:
image.png

我使用getData函数模拟http请求,假如http请求出错,如何不取消当前subject的订阅?即继续处理后续11, 13, 15, 17这些数据,我使用了catchError但是不生效。


目前已知的一个解决方法是把pipe放到switchMap里面,但是这样嵌套很不美观,求其他解决方式?

subject
  .pipe(switchMap(value => {
    return getData(value)
      .pipe(tap(value => console.log(value)))
      .pipe(catchError(err => {
        console.error(err);
        return of(null);
      }))
  }))
  .subscribe();

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

陌路黄昏 2022-09-19 03:07:12

https://stackblitz.com/edit/r...

你可以把catchError放到getData中使用,这样就不会中断后面的后续的流了.

function getData(value) {
  return of(value).pipe(
    map(value => {
      // 模拟http请求报错
      if (value % 2 === 0) {
        throw new Error("不是奇数");
      }
      return value;
    }),
    catchError(err => {
      console.error(err);
      return of(null);
    })
  );
}

const subject = new BehaviorSubject<number>(1);

subject
  .pipe(
    switchMap(value => {
      return getData(value);
    }),
    filter(v=>!!v), // 增加一个 filte 过滤空值
    tap(value => console.log(value))
  )
  .subscribe();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文