@ngrx Effect 没有第二次运行
Posted
技术标签:
【中文标题】@ngrx Effect 没有第二次运行【英文标题】:@ngrx Effect does not run the second time 【发布时间】:2017-10-26 02:17:29 【问题描述】:我刚刚开始了解@ngrx/store 和@ngrx.effects,并在我的Angular/Ionic 应用程序中创建了我的第一个效果。它第一次运行正常,但如果我再次将事件发送到商店(即再次单击按钮时),什么也没有发生(没有进行网络调用,控制台日志中没有任何内容)。有什么明显的我做错了吗?效果如下:
@Effect() event_response$ = this.action$
.ofType(SEND_EVENT_RESPONSE_ACTION)
.map(toPayload)
.switchMap((payload) => this.myService.eventResponse(payload.eventId,payload.response))
.map(data => new SentEventResponseAction(data))
.catch((error) => Observable.of(new ErrorOccurredAction(error)));
谢谢
【问题讨论】:
【参考方案1】:听起来好像发生了错误。在这种情况下,catch
返回的 observable 中的动作将被发送到效果的流中,然后效果将完成 - 这将阻止效果在错误动作发出后运行。
将map
和catch
移动到switchMap
:
@Effect() event_response$ = this.action$
.ofType(SEND_EVENT_RESPONSE_ACTION)
.map(toPayload)
.switchMap((payload) => this.myService
.eventResponse(payload.eventId, payload.response)
.map(data => new SentEventResponseAction(data))
.catch((error) => Observable.of(new ErrorOccurredAction(error)))
);
在switchMap
中组合catch
会在发生错误时阻止效果完成。
【讨论】:
这是否意味着使用 Angular 的全局错误处理程序无法使用效果? ***.com/questions/47896171/… 对于pipe
able 运算符和catchError
仍然如此。我花了一段时间才找到这个问题!谢谢。
供参考 - 您可以在不进入回调地狱的情况下执行此操作,只需在管道末尾添加一个 catchError:github.com/ngrx/platform/issues/646#issuecomment-398640097
@亚当尼斯。但是,我建议返回 caught.pipe(startWith(/* error action */))
而不是通过商店显式调度 - 正如链接的 GitHub 评论中所做的那样 - 我认为这不是我认为应该做的事情。
@cartant - 这又回到了管道的内部。你能做到吗:.pipe(...,catchError((err,caught) => caught),startWith(() => /* error action */)
?我发现在效果中做 store.dispatch 也很恶心,我只是觉得它比把管道放在管道里更恶心。【参考方案2】:
您必须将map()
和catchError()
移动到swithchMap()
,如下所示
@Effect()
public event_response$ = this.action$.pipe(
ofType(SEND_EVENT_RESPONSE_ACTION),
switchMap((payload) =>
return this.myService.eventResponse(payload.eventId,payload.response).pipe(
map((data: DataType) => new SentEventResponseAction(data)),
catchError((error) => Observable.of(new ErrorOccurredAction(error)))
)
);
);
请注意,myService
中的 evetResponse()
方法应该返回一个 observable 以便之后使用管道。
如果你在服务中的方法返回Promise
,你可以通过使用rxjs包中的from
将它转换成一个observable,如下所示:
import from from 'rxjs';
...
const promise = this.myService.eventResponse(payload.eventId,payload.response);
const observable = from(promise);
return observable.pipe(...
更多详细介绍请看link
【讨论】:
以上是关于@ngrx Effect 没有第二次运行的主要内容,如果未能解决你的问题,请参考以下文章
如何在ngrx/effect(redux-observable)中调度多个动作?