【问题标题】:How to start processing after the user finishes typing with RxJS?用户使用 RxJS 完成输入后如何开始处理?
【发布时间】:2020-03-14 04:50:59
【问题描述】:

我有一个输入元素,我想在其中显示一个自动完成解决方案。我尝试使用 RxJS 控制 HTTP 请求的数量。我想做的是:HTTP 请求仅在用户停止输入 1 秒后开始。

我有这个代码:

of(this.inputBox.nativeElement.value)
  .pipe(
    take(1),
    map((e: any) => this.inputBox.nativeElement.value),
    // wait 1 second to start
    debounceTime(1000),
    // if value is the same, ignore
    distinctUntilChanged(),
    // start connection
    switchMap(term => this.autocompleteService.search({
      term: this.inputBox.nativeElement.value
    })),
  ).subscribe((result: AutocompleteResult[]) => {
    console.log(result);
  });

问题是debounceTime(1000) 没有等待继续管道。 switchMap 在每个 keyup 事件之后立即启动。

如何在用户完成输入后等待 1 秒?

【问题讨论】:

    标签: rxjs rxjs6


    【解决方案1】:

    问题是您的链以of(this.inputBox.nativeElement.value).pipe(take(1), ...) 开头,所以看起来您在每次按键时都在创建一个新链(带有一个新的去抖动计时器)。

    相反,您应该只有一个链并将值推送到其源:

    const keyPress$ = new Subject();
    
    ...
    
    keyPress$
      .pipe(
        debounceTime(1000),
        ...
      )
    
    ...
    
    keyPress$.next(this.inputBox.nativeElement.value);
    

    【讨论】:

      【解决方案2】:

      为什么不用fromEvent 创建一个流?

      我发现没有必要使用distinctUntiChanged,因为input 事件仅在发生更改时触发(即用户添加/删除内容)。所以通过流的文本总是不同的。

      const {fromEvent} = rxjs;
      const {debounceTime, map} = rxjs.operators;
      
      const text$ =
        fromEvent(document.querySelector('input'), 'input')
          .pipe(
            debounceTime(1000),
            map(ev => ev.target.value));
      
      text$.subscribe(txt => {
        console.log(txt);
      });
      <script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.5.4/rxjs.umd.min.js"></script>
      <input/>

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-09-10
        • 2011-08-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多