10

如果我在我的应用程序模块中声明,我会尝试了解 typeof 效果在 ngrx 中是如何工作的:

....

@NgModule({
    imports: [
        EffectsModule.forRoot([TodosEffectsService])
],

....

我肯定会写效果文件:

@Effect() createTodos$ = this.actions$
.ofType(CREATE_TASK)
    .map(() => {
        console.log('called');
            return { type: 'OTHER'};
});

@Effect() addTodos$ = this.actions$
.ofType(CREATE_TASK)
    .map(() => {
        console.log('called');
            return { type: 'OTHER'};
});

我试着理解,现在在运行时我调度了一个动作 this.action$ 被订阅并且每次执行 ofType 来匹配类型?或 ofType 一次执行!?

如果它调用一次,当我调度操作时,效果如何知道每次女巫效果订阅/执行?

谢谢大家!

4

4 回答 4

18

简而言之,当.ofType()被调用时,它订阅动作的源流并将匹配的动作推送到结果流。所以它确实被调用了一次。

如果我们查看源代码,我们会看到在底层ofType使用库filter运算符rxjs,这意味着this.action$.ofType(CREATE_TASK)可以扩展为

this.action$.filter(action => action.type === CREATE_TASK)

filter可以从rxjs docs中找到有关如何工作的说明:

与众所周知的Array.prototype.filter方法类似,此运算符从源 Observable 获取值,将它们传递给一个predicate函数,并且只发出那些产生的值true

值得注意的是,您的每个效果都将一个 observable ( this.action$) 作为输入并返回一个新的 observable,该新的 observable 在初始化效果时只订阅一次。返回的 observable 定义了输入 observable 中的操作如何转换的方式,但它不影响源 observable 本身。

在您的示例ofType()方法中,返回一个新的 observable,它“侦听” this.action$observable 并仅发出满足条件的操作action.type === CREATE_TASK。然后是map运算符,它还返回一个新的 observable,它“监听”ofType()调用返回的 observable,并根据您传递的投影函数将它接收到的每个操作转换为新值。但是所有这些可观察对象都只创建一次,在初始化时,当您调度操作时,它们只是“流动”通过可观察对象,被过滤和转换。

您可能还想更加熟悉rxjs. 我建议你查看André Staltz 的“你将学习 RxJS”演讲,它应该让你直观地了解什么是可观察对象以及它们是如何工作的。

于 2017-08-07T00:21:31.630 回答
2

this.actions$ .ofType(CREATE_TASK) 将在每次调度您的操作时调用,在您的减速器案例执行后。像减速机

switch(action) {
case youractionsname.CREATE_TASK : {
// pure function logic here
   }
}

如果您有任何具有“CREATE_TASK”类型的效果,则第一个减速器将执行,然后它将生效。在订阅模式中,您订阅的任何内容都将是回调函数,它将根据条件存储在引擎盖下的数组中。当您根据条件调度动作时,所有函数都会调用满足条件的人。

于 2018-07-23T18:49:22.100 回答
1

关键是 ofType 没有在 ngrx/effects 内的 Actions 类中导出,因此您可以像下面这样使用它: 1- import ofType from ngrx/effects 这将是

import { Injectable } from "@angular/core";

import { Effect, Actions, ofType } from "@ngrx/effects";
import * as omid from "@ngrx/effects";
import { of } from "rxjs";
import { map, switchMap, catchError } from "rxjs/operators";
@Injectable()
export class PizzasEffects {
  constructor(
    private actions$: Actions,
    private pizzaService: frtomServices.PizzasService
  ) {}

  @Effect()
  LoadPizzas$ = this.actions$.pipe(
    ofType(pizzaActions.LOAD_PIZZAS),
    switchMap(() => {
      return this.pizzaService.getPizzas().pipe(
        map(pizzas => new pizzaActions.LoadPizzasSuccess(pizzas)),
        catchError(error => of(new pizzaActions.LoadPizzasFail(error)))
      );
    })
  );
}
于 2019-01-14T01:37:47.987 回答
0

您还可以从每个效果中分派一系列动作。

从媒体阅读这篇文章

于 2020-10-27T16:56:33.450 回答