Angular:如何使用Observable.timer()和switchMap去除函数调用?

时间:2018-02-02 12:58:27

标签: angular observable

这是我的方法:

\s

我想在后端调用之间设置一个延迟,这样我的方法就不会在使用Observable.timer()和switchMap的每次击键时被调用。

作为示例我从异步验证器获取此代码正是我想要的

  filter(value) {    
    this.backendCall(value)    
  }

...但我努力将其应用于我的方法。这就是我的尝试:

export function createAsyncValidator(checkFn: (value: string) => Observable<Boolean>, errorMessage: string) {
    return (control: AbstractControl): Observable<ValidationErrors> => {
        return Observable.timer(500).switchMap(() => {
            return checkFn(control.value)
                .map(result => (result ? null : { [errorMessage]: true }));
        });
    }
}

确实应用了延迟,但记录了所有值。我期待swithMap能够取消延迟在延迟期间到达的那些可观察物。 我在这里缺少什么?

2 个答案:

答案 0 :(得分:2)

在订阅observable之前使用debounceTime

在您的过滤器函数中,使用该值发出一个事件,并在订阅中使用添加的debounceTime作出反应。

filter(value: ValueType) {
    this.filterSubject.next(value);
}

ngOnInit() {
    this.filterSubject = new Subject<ValueType>();
    this.filterSubject.debounceTime(500).subscribe((value: ValueType) => {
        this.backendCall(value);
    });
}

答案 1 :(得分:0)

首先,我认为你错过了那里的回复声明:

filter(value) {
    -->return<-- Observable.timer(500).switchMap(() => {
      return Observable.of(value);
    }).subscribe(() => {
      console.log('filter', value);
      // this.backendCall(value)
    });
  }

但我真的不明白你试图把它放在这里的逻辑。

在此评论之后编辑:

  

我希望只有在打字完成后才会发生后端调用   (例如延迟一秒)。节气门会发送我的第一个   立即按键到后端

您可以简单地使用debounceTime运算符来实现此类行为。

doc here

因此,如果您的来源是输入,您可以这样使用:

<myFormControl>.valueChanges.debounceTime(500).flatMap(value => {
    return this.backendCall(value);
}).subscribe();

这样,在您停止输入后,backendCall将被调用500ms。