【问题标题】:can ngrx store.dispatch be throttled / debounced or can ngrx actions be throttled / debounced?ngrx store.dispatch 是否可以被限制/去抖动,或者 ngrx 操作是否可以被限制/去抖动?
【发布时间】:2018-07-20 10:21:49
【问题描述】:

我正在使用带有角度 6 的 ngrx 6

在我的 ngrx 商店 devtools 中,我发现我的一项操作触发的频率超出了我的预期。它并没有破坏应用程序,它只是使 devtools 输出混乱。

我正在通过以下方式发送操作:

this.store.dispatch(new RecentSearchesRequestedAction())

例如,我怎样才能最好地去抖动/限制它,使其每秒调度不超过一次? ngrx 有内置解决方案吗?我知道我可以花时间弄清楚为什么动作如此频繁地触发,但我真的没有时间。实现这一目标的最佳做法是什么?谢谢

【问题讨论】:

  • 如果多次派发,一定是由于效果或其他原因造成的循环调用。你能提供你的减速器和效果的代码吗?据我所知,没有办法干扰操作的调度方式。

标签: angular ngrx


【解决方案1】:

最好的解决方案是去抖动调用 this.store.dispatch 的任何东西,这将在 ngrx 之外。

你可以限制ngrx的输出端,例如:

this.store.select((x) => x.property)
.pipe(
    debounceTime(1000)
).subscribe((v) => console.log(v));

... 最多每秒记录一次 x.property 的值。但是要停止输入,您需要在调用调度之前进行节流。

【讨论】:

    【解决方案2】:

    这是对已接受答案的补充答案,并深入探讨了有关实际放置去抖动的位置的更多细节。

    当使用FormControls 时,由于 valueChanges (example) 的存在很容易去抖动:

    this.searchField.valueChanges
      .debounceTime(400)
        .switchMap(term => this.searchService.search(term))
        .subscribe((result) => {
            this.result = result.items
        });
    

    这依赖于switchMap 函数,该函数取消现有调用并保留最新调用。

    使用自定义控件时,取消通常需要自定义代码(example for a Kendo control 不会发出更改,但依赖于事件):

    应用去抖动的值更改指令后

    import { Directive, Input, HostListener, OnDestroy, Output, EventEmitter } from '@angular/core';
    import { Subject, Subscription } from 'rxjs';
    import { debounceTime } from 'rxjs/operators';
    
    @Directive({
      selector: '[afterValueChanged]'
    })
    export class AfterValueChangedDirective implements OnDestroy {
      @Output()
      public afterValueChanged: EventEmitter<any> = new EventEmitter<any>();
    
      @Input()
      public valueChangeDelay = 300;
    
      private stream: Subject<any> = new Subject<any>();
      private subscription: Subscription;
    
      constructor() {
        this.subscription = this.stream
          .pipe(debounceTime(this.valueChangeDelay))
          .subscribe((value: any) => this.afterValueChanged.next(value));
      }
    
      ngOnDestroy(): void {
        this.subscription.unsubscribe();
      }
    
      @HostListener('valueChange', [ '$event' ])
      public onValueChange(value: any): void {
        this.stream.next(value);
      }
    }
    

    用法

    <kendo-numerictextbox
      (afterValueChanged)="onAfterValueChange($event)"
      (valueChange)="onValueChange($event)">
    </kendo-numerictextbox>
    
    public onAfterValueChange(value: number): void {
       this.value = value;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-02-01
      • 2021-10-24
      • 1970-01-01
      • 2012-07-13
      • 2018-10-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多