ngrx效果:由一个效果调度的动作是否立即被其他效果处理? [英] ngrx Effects: Are actions dispatched by one effect processed immediately by other effects?
问题描述
我有一个带有四个ngrx动作的Angular(2)应用程序:
I have an Angular (2) app with four ngrx actions:
- 开始
- 减速器未处理(状态不变)
- ngrx Effect调用异步任务并映射到SUCCESS或ERROR
- START
- Not processed by the reducer (no state change)
- ngrx Effect calls an async task and maps to SUCCESS or ERROR
- 由减速器处理
- ngrx效果映射到ADVANCE
- 未由减速器处理
- ngrx效果导航到其他路线
- 由减速器处理
- 没有效果
问题在于捕获ADVANCE的效果似乎在处理SUCCESS的reducer之前运行
以下是效果代码:
@Effect() start$ = this.actions$ .ofType('START') .map(toPayload) .switchMap(input => doAsyncTask(input) .map(result => ({type: 'SUCCESS', payload: result})) .catch(error => ({type: 'ERROR', payload: error}))); @Effect() success$ = this.actions$ .ofType('SUCCESS') .map(() => ({type: 'ADVANCE'})); @Effect({dispatch: false}) advance$ = this.actions$ .ofType('ADVANCE') .withLatestFrom(this.store$.select(state => state.route)) .map(action_route => action_route[1]) .do(route => this.router.navigate([route.foo.bar]));
我遇到的错误是
Cannot read property 'bar' of null
.属性foo
由处理SUCCESS的reducer设置.The error that I am getting is
Cannot read property 'bar' of null
. The propertyfoo
is set by the reducer that processes SUCCESS.如果我在SUCCESS效果上添加延迟,则效果很好:
@Effect() success$ = this.actions$ .ofType('SUCCESS') .delay(1) .map(() => ({type: 'ADVANCE'}));
但是必须加上这个延迟对我来说没有意义.
But having to add this delay doesn't make sense to me.
我到处都添加了
console.log
语句,输出看起来像这样:I added
console.log
statements everywhere and the output looks like this:- 成功效果
- 高级效果(显示route.foo === null)
- 成功的减速器(显示route.foo ===某物)
- 错误
我希望SUCCESS效果和SUCCESS reducer在ADVANCE效果之前运行.
I expected the SUCCESS effect and the SUCCESS reducer to run before the ADVANCE effect.
我做错什么了吗?
指望减速器按照调度的顺序处理动作是否不正确?
版本:
- @ angular/cli:1.0.0-beta.32.3
- 节点:7.5.0
- os:达尔文x64
- @ angular/common:2.4.7
- @ angular/compiler:2.4.7
- @ angular/core:2.4.7
- @ angular/forms:2.4.7
- @ angular/http:2.4.7
- @ angular/platform-browser:2.4.7
- @ angular/platform-browser-dynamic:2.4.7
- @角度/路由器:3.4.7
- @ angular/cli:1.0.0-beta.32.3
- @ angular/compiler-cli:2.4.7
- @ ngrx/core @ 1.2.0
- @ ngrx/effects @ 2.0.0
- @ ngrx/store @ 2.2.1
- rxjs:5.1.1
- @angular/cli: 1.0.0-beta.32.3
- node: 7.5.0
- os: darwin x64
- @angular/common: 2.4.7
- @angular/compiler: 2.4.7
- @angular/core: 2.4.7
- @angular/forms: 2.4.7
- @angular/http: 2.4.7
- @angular/platform-browser: 2.4.7
- @angular/platform-browser-dynamic: 2.4.7
- @angular/router: 3.4.7
- @angular/cli: 1.0.0-beta.32.3
- @angular/compiler-cli: 2.4.7
- @ngrx/core@1.2.0
- @ngrx/effects@2.0.0
- @ngrx/store@2.2.1
- rxjs: 5.1.1
推荐答案
要回答您的结论性问题:
To answer your concluding questions:
- 我做错什么了吗?
- Am I doing something wrong?
- 不,我不认为您做错了任何事.
- 指望减速器按照调度的顺序处理动作是否不正确?
- Is it incorrect to expect that actions are processed by the reducers in the same order that they are dispatched?
- 该顺序似乎合乎逻辑,但显然您目前无法期待
- https://github.com/ngrx/effects/issues/58
- https://github.com/ngrx/store/issues/279
- /ReactiveX/rxjs/issues/2155 (也很难与该链接相关联)
- https://github.com/ngrx/effects/issues/58
- https://github.com/ngrx/store/issues/279
- /ReactiveX/rxjs/issues/2155 (too little reputation to link to this one as well)
似乎是导致此行为的错误.因为您直接映射到另一个操作,所以您很可能正在经历它.通常,如果您具有异步操作或类似的操作,则reducer有时间在效果开始监听下一个动作之前完成.
There seems to be a bug causing this behaviour. You are most probably experiencing it since you are directly mapping to another action. Usually, if you have an asynchronous operation or something like that, the reducer has time to finish before the effect listening to the next action starts.
也许这不是您问题的一部分,但是解决您指定问题的方法是,借助有效负载直接在SUCCESS中导航至新路线,或将有效负载传递给ADVANCE.
Perhaps not a part of your question, but a solution to your specified problem would be to navigate to your new route directly in SUCCESS with the help of your payload, or pass the payload to ADVANCE.
下面的链接是与您的效果,存储和rxjs项目相关的已报告问题:
Links below are reported issues in effects-, store- and rxjs-projects that are related to yours:
似乎他们正在努力:)
这篇关于ngrx效果:由一个效果调度的动作是否立即被其他效果处理?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!