@ngrx选择器并行发出两次

时间:2018-09-07 08:23:12

标签: rxjs ngrx

我有一个非常简单的选择器

export const isLoading = createSelector(
  state => state.$loading
);

和两个动作StartLayoutNavigationActionEndLayoutNavigationAction,它们分别相应地设置了$loading标志。 我一旦调用了这些函数,我的操作就会被记录下来:

ACTION – [Layout] Start navigation StartLayoutNavigationAction {layout: "login", type: "[Layout] Start navigation"}
ACTION – [Layout] End navigation EndLayoutNavigationAction {type: "[Layout] End navigation"}

因此,我们会假设选择器在第一个动作被调用时发出一次,而在第二个动作被调用时发出一次。之间没有任何动作。

但是:

选择器似乎并行发出两次。我通过以下方式进行了管道传输:

layoutLoading$: Observable<boolean> = this.store.pipe(
  select(isLoading),
  distinctUntilChanged((x, y) => {
    console.log("Comparison:", x, y);
    return x === y;
  }),
  tap(value => console.log("New val:", value))
);

这是输出:

ACTION – [Layout] Start navigation StartLayoutNavigationAction {layout: "login", type: "[Layout] Start navigation"}
Comparison:  false true
New val: true
Comparison: false true
New val: true
ACTION – [Layout] End navigation EndLayoutNavigationAction {type: "[Layout] End navigation"}
Comparison: true false
New val: false
Comparison: true false
New val: false

我弄错了吗?这是预期的行为吗?

2 个答案:

答案 0 :(得分:1)

基于评论

  

您确定layoutLoading $仅有一个订阅吗?对于   例如,您有多个异步管道,多个组件实例。 -@越野车

const source$ = of(1).pipe(
  tap(value => console.log("New val:", value))
);

source$.subscribe();
source$.subscribe();
// 1
// 1
  

好吧,没错,我有两个异步订阅。我不知道   这适用于每个订阅。所以当我想对不同   更改(除了异步管道),我将需要一秒钟   可观察的管道,对吗? -@GiacomoVoß

是的,如果我理解正确:

source$
  .pipe(distinctUntilChanged(fn))
  .subscribe(/* do something */)

答案 1 :(得分:0)

每次状态更改时,选择器都会执行。这是因为它的参数是整个状态。