在没有内部观察的情况下,如何处理NGRX效应中的错误?

发布于 2025-02-11 16:41:53 字数 593 浏览 1 评论 0 原文

考虑一个可以引发异常的正常功能:

function canThrow(){
  ...
  throw 'error';
}

我想在ngrx效果中使用它:

public myEffect$ = createEffect(() =>
    this.actions$.pipe(
      ofType(DoSomethingAction),
      map(() =>
        canThrow(),
      ),
      map(() => SucceededAction()),
      catchError(() => of(FailedAction())),
    ),
  );

但是,这会导致失败被排放然后完成,这杀死了效果 - 类似于 cather> catcherror 不是从返回可观察到的函数中管道的。

这里 canthrow dis 不是返回可观察的。

我该如何构建代码以便处理错误,但不会通过完成终止效果?

Consider a normal function that can throw an exception ie:

function canThrow(){
  ...
  throw 'error';
}

I want to use that in an NGRX effect:

public myEffect$ = createEffect(() =>
    this.actions$.pipe(
      ofType(DoSomethingAction),
      map(() =>
        canThrow(),
      ),
      map(() => SucceededAction()),
      catchError(() => of(FailedAction())),
    ),
  );

However this results in FailedAction being emitted then completing, which kills the effect - similarly to when catchError is not piped from a function returning an observable.

Here canThrow does not return an observable.

How can I structure the code so that error is handled but the effect is not terminated via the completion?

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

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

发布评论

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

评论(2

去了角落 2025-02-18 16:41:53

我建议使用 switchmap canthrow 不返回可观察的操作员。 https://stackblitz.com/edit/redit/rxjs-mk5bla?file= index。 TS

您可以在这里了解更多信息:


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

of({
  type: 'some action',
})
  .pipe(
    switchMap(() => {
      try {
        const result = throwError();
        return of(result).pipe(map(() => ({ type: 'success action' })));
      } catch (error) {
        return of({ type: 'failed action' });
      }
    })
  )
  .subscribe(console.log);



function throwError() {
  if (Math.random() > 0) {
    throw new Error('kaboom');
  } else {
    return 'some data';
  }
}

I recommend using a flattening operator like switchMap assuming canThrow does not return an observable. https://stackblitz.com/edit/rxjs-mk5bla?file=index.ts

You can learn more here: https://www.learnrxjs.io/learn-rxjs/operators/transformation/switchmap


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

of({
  type: 'some action',
})
  .pipe(
    switchMap(() => {
      try {
        const result = throwError();
        return of(result).pipe(map(() => ({ type: 'success action' })));
      } catch (error) {
        return of({ type: 'failed action' });
      }
    })
  )
  .subscribe(console.log);



function throwError() {
  if (Math.random() > 0) {
    throw new Error('kaboom');
  } else {
    return 'some data';
  }
}

菊凝晚露 2025-02-18 16:41:53

我提出了两种实现这一目标的方法:

映射可以尝试/捕获而无需观察到

沿着亚历克斯的回答,这是一种使用 try..catch 的势在必行的方法 switchmap 和返回的动作转换为可观察到的不需要:

public myEffect$ = createEffect(() =>
    this.actions$.pipe(
      ofType(DoSomethingAction),
      map(() => {
        try {
          canThrow();
          return SucceededAction();
        }
        catch {
          return FailedAction();
        }
      }),
    ),
  );

defer/of and catherror

更面向RXJS的解决方案,该解决方案可创建可观察的包装 canthrow 和管道响应,允许使用 catherror

public myEffect$ = createEffect(() =>
    this.actions$.pipe(
      ofType(DoSomethingAction),
      switchMap(() =>
        defer(() => of(canThrow())),
      ).pipe(
        map(() => SucceededAction()),
        catchError(() => of(FailedAction())),
      ),
    ),
  );

I came up with 2 ways of achieving this:

map to try/catch without observables

Along the lines of Alex's answer, a somewhat imperative approach using a try..catch but the switchMap and conversion of returned actions to observables is not required:

public myEffect$ = createEffect(() =>
    this.actions$.pipe(
      ofType(DoSomethingAction),
      map(() => {
        try {
          canThrow();
          return SucceededAction();
        }
        catch {
          return FailedAction();
        }
      }),
    ),
  );

switchMap with defer/of and catchError

A more rxjs oriented solution, which creates an observable wrapping canThrow and pipes the response which allows use of catchError:

public myEffect$ = createEffect(() =>
    this.actions$.pipe(
      ofType(DoSomethingAction),
      switchMap(() =>
        defer(() => of(canThrow())),
      ).pipe(
        map(() => SucceededAction()),
        catchError(() => of(FailedAction())),
      ),
    ),
  );
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文