Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ssis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用rjxs而不是setTimeout函数订阅更优雅的方式?_Javascript_Angular_Typescript_Rxjs_Rxjs6 - Fatal编程技术网

Javascript 使用rjxs而不是setTimeout函数订阅更优雅的方式?

Javascript 使用rjxs而不是setTimeout函数订阅更优雅的方式?,javascript,angular,typescript,rxjs,rxjs6,Javascript,Angular,Typescript,Rxjs,Rxjs6,我有一个update()方法,用它搜索表中的某些条目,并更新/过滤输入字段中每个击键的条目 我的目标是在每次击键后等待大约400毫秒,然后将请求发送到后端,这样我就避免了太多无意义的请求 目前我已经用setTimeout()函数实现了它,但我确信RxJS有一种更优雅的方式 update(searchInput: string) { setTimeout(() => { this.myService.search(searchInput) .subscri

我有一个
update()
方法,用它搜索表中的某些条目,并更新/过滤输入字段中每个击键的条目

我的目标是在每次击键后等待大约400毫秒,然后将请求发送到后端,这样我就避免了太多无意义的请求

目前我已经用
setTimeout()
函数实现了它,但我确信RxJS有一种更优雅的方式

  update(searchInput: string) {
    setTimeout(() => {
      this.myService.search(searchInput)
      .subscribe((res) => {
        this.myArray.content = res;
      });
    }, 400);
  }

有人知道吗?

我在代码中留下了一些注释:

const search = fromEvent(searchInput, 'input').pipe(
  debounceTime(1000), // Time in milliseconds between key events
  distinctUntilChanged(), // If previous query is different from current   
  map(event => event.target.value) // get value,
  filter(query => query) // if character length greater then 0,
  tap(query => console.log(`About to make an API call with query: ${query}`)),
  switchMap(getCars) // Your api call
);

search.subscribe(successCallback);

您可以执行以下操作:

在HTML中:

<input type="text" #myId="ngModel" [(ngModel)]="data" />
}

尝试使用
debounce()
distinctuntellechange()

handleFilterEvent=新主题();
恩戈尼尼特(){
这是handleFilterEvent
.debounceTime(500)
.distinctUntilChanged()
.subscribe(值=>{
this.myService.search(searchInput)
.订阅((res)=>{
this.myArray.content=res;
});
});
}
onSearchChange(值){
如果(值){
this.handleFilterEvent.next(值);
}
}
HTML:


您可以使用
fromEvent
Viewchild

只需参考ViewChild,如下所示:

@ViewChild('yourInput') inputName: any;
然后,您可以简单地使用:

fromEvent(this.inputName.nativeElement, 'keyup')
            .pipe(
                map((k: any) => k.target.value),
                debounceTime(1000)
            )
            .subscribe(value => {
              foo();
            });

这是真正的RXJS方式,我已将
myArray.content
更改为
可观察的
,因为这样可以使用管道和映射。这将防止多个请求,更具体地说,它将在开始新的搜索之前取消订阅以前的搜索

searchedInput$=新主题();
myArray:{content:Observable}={};
构造函数(myService:any){
this.myArray.content=this.searchedInput$.pipe(
distinctUntilChanged(),
去BounceTime(400),
switchMap(输入=>myService.search(输入)),
);
}
更新(搜索输入:字符串):无效{
this.searchedInput$.next(searchInput);
}

您要找的是。 它等待x毫秒后才发出任何信号。 将它与其他操作符相结合以避免API过载将是一个不错的选择

你的可观察到的

const search$ = fromEvent(search, 'input').pipe(
  debounceTime(400), // Wait 400 MS before outputting
  distinctUntilChanged(), // Only output unique values
  map(event => event.target.value), // Extract the value of the search
  switchMap((search) => service.doApi(search)) // SwitchMap to cancel a previous search if it wouldn't have completed
)
search$.subscribe()  // These might leak. Keep them in an array and clean them up when the component unloads
其中,搜索元素将是组件的viewChild

import { Component, ElementRef, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { fromEvent, Subscription } from 'rxjs';
import { debounceTime, distinctUntilChanged, map, switchMap } from 'rxjs/operators';

@Component({
  selector: 'app-component',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit, OnDestroy {
  @ViewChild('yourInput', {static: true}) search: ElementRef;

  searchSubscription: Subscription;

  ngOnInit(): void {
    const search$ = fromEvent(this.search.nativeElement, 'input').pipe(
      debounceTime(400), // Wait 400 MS before outputting
      distinctUntilChanged(), // Only output unique values
      map((event: KeyboardEvent) => (event.target as HTMLInputElement).value), // Extract the value of the search
      switchMap((search) => service.doApi(search)) // SwitchMap to cancel a previous search if it wouldn't have completed
    )  // Lives forever
    this.searchSubscription = search$.subscribe()
  }

  ngOnDestroy(): void {
    this.searchSubscription.unsubscribe()
  }
}



您需要使用debounce而不是。如果您使用管道语法并为搜索请求添加
switchMap
,这将是完美的。感谢你的帮助。但通过这种方式,我得到了错误:“属性‘target’不存在于由map((event)=>event.target.value)生成的类型‘unknown.ts(2339)’。
fromEvent
数据类型当前为类型{}。我已经更新了我的答案,将事件类型缩小为keyboardEvent,因为dom中实际上缺少InputEvent类型。typingsNow它说:错误错误:未捕获(承诺中):类型错误:无法读取Undefinedah的属性“nativeElement”,新手错误。nativeElement仅在ngOnInit中可用。让我更新一下我的回答,我还认为这与生命周期有关。Thnx。
fromEvent(this.inputName.nativeElement, 'keyup')
            .pipe(
                map((k: any) => k.target.value),
                debounceTime(1000)
            )
            .subscribe(value => {
              foo();
            });
const search$ = fromEvent(search, 'input').pipe(
  debounceTime(400), // Wait 400 MS before outputting
  distinctUntilChanged(), // Only output unique values
  map(event => event.target.value), // Extract the value of the search
  switchMap((search) => service.doApi(search)) // SwitchMap to cancel a previous search if it wouldn't have completed
)
search$.subscribe()  // These might leak. Keep them in an array and clean them up when the component unloads
import { Component, ElementRef, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { fromEvent, Subscription } from 'rxjs';
import { debounceTime, distinctUntilChanged, map, switchMap } from 'rxjs/operators';

@Component({
  selector: 'app-component',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit, OnDestroy {
  @ViewChild('yourInput', {static: true}) search: ElementRef;

  searchSubscription: Subscription;

  ngOnInit(): void {
    const search$ = fromEvent(this.search.nativeElement, 'input').pipe(
      debounceTime(400), // Wait 400 MS before outputting
      distinctUntilChanged(), // Only output unique values
      map((event: KeyboardEvent) => (event.target as HTMLInputElement).value), // Extract the value of the search
      switchMap((search) => service.doApi(search)) // SwitchMap to cancel a previous search if it wouldn't have completed
    )  // Lives forever
    this.searchSubscription = search$.subscribe()
  }

  ngOnDestroy(): void {
    this.searchSubscription.unsubscribe()
  }
}