ngrx效果:由其他效果立即处理的一种效果调度的动作是什么?

Car*_*gas 5 ngrx ngrx-effects angular

我有一个带有四个ngrx动作的Angular(2)应用程序:

  • 开始
    • 减速机未处理(无状态变化)
    • ngrx Effect调用异步任务并映射到SUCCESS或ERROR
  • 成功
    • 由reducer处理
    • ngrx效果映射到ADVANCE
  • 预先
    • 没有由减速机处理
    • ngrx效果导航到不同的路线
  • 错误
    • 由reducer处理
    • 没有效果

问题是捕获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]));
Run Code Online (Sandbox Code Playgroud)

我得到的错误是Cannot read property 'bar' of null.该属性foo由处理SUCCESS的reducer设置.

如果我为SUCCESS效果添加一个延迟,那么一切都很好:

@Effect() success$ = this.actions$
    .ofType('SUCCESS')
    .delay(1)
    .map(() => ({type: 'ADVANCE'}));
Run Code Online (Sandbox Code Playgroud)

但是不得不加上这个延迟对我来说没有意义.

console.log在各处添加了语句,输出如下所示:

  1. 成功效果
  2. ADVANCE效果(显示route.foo === null)
  3. SUCCESS减速机(显示route.foo ===的东西)
  4. 错误

我期望SUCCESS效果和SUCCESS减速器在ADVANCE效果之前运行.

难道我做错了什么?

期望reducers以与调度它们相同的顺序处理操作是不正确的吗?


版本:

  • @ angular/cli:1.0.0-beta.32.3
  • 节点: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-b​​rowser:2.4.7
  • @ angular/platform-b​​rowser-dynamic:2.4.7
  • @ angular/router:3.4.7
  • @ angular/cli:1.0.0-beta.32.3
  • @ angular/compiler-cli:2.4.7
  • @ NGRX /核心@ 1.2.0
  • @ NGRX /效应@ 2.0.0
  • @ NGRX /存储@ 2.2.1
  • rxjs:5.1.1

Gil*_*niv -2

ngex/effects 的目的是充当基于 redux 的环境中的中间件。

在此输入图像描述

因此,您在这里基本上所做的就是调用“成功”操作,该操作应该在减速器上工作并继续执行另一个操作,即中间件。但这是 effecs 的辅音,它应该拦截动作并自行处理它们,只有在异步处理它之后才调度动作。

那么这里发生了什么?您将成功分派到两个不同的地方,一个应该由减速器处理,另一个由中间件处理。我不确定它是否总是这样,但中间件会在传入的操作到达减速器之前拦截它。我认为如果你稍微修改一下代码它应该可以工作。尝试做类似的事情:

@Effect() start$ = this.actions$
    .ofType('START')
    .map(toPayload)
    .switchMap(input => doAsyncTask(input)
        .map(result =>{
               this.store$.dispatch(
               {type: 'SUCCESS',
                payload: result
                });
               this.store$.dispatch(
               {type: 'ADVANCE'})

}

        .catch(error => ({type: 'ERROR', payload: error})));
Run Code Online (Sandbox Code Playgroud)

你明白我在这里做什么吗?我已经删除了拦截“成功”的中间件,因此“成功”不会到达减速器。在它之后,它会调度另一个“高级”类型的操作,该操作应该在“成功”处理完成后到达您的中间件。

希望能帮助到你。