首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >http服务调用的Debounce输入

http服务调用的Debounce输入
EN

Stack Overflow用户
提问于 2017-06-05 07:20:01
回答 2查看 402关注 0票数 1

我目前所做的是将输入双向绑定到appRequestParams.appName,并且在每个keyup事件上,将调用fetchApps()方法。

我试图揭穿输入,使其不会立即触发后端http请求的每一个键。

我已经阅读了如何去做这件事,在这里,我已经拿出来了。

代码语言:javascript
复制
<input #searchBox id="search" mdInput placeholder="Search by list of apps" (keyup)="search(searchBox.value)" />

类型标

代码语言:javascript
复制
private searchTerms = new Subject<string>();

search(value: string): void {
       this.searchTerms.next(value);
   }


fetchApps() {
       this.appService.query({
           appName: this.appRequestParams.appName ? this.appRequestParams.appName : null,
       }).subscribe(
           (res: ResponseWrapper) => this.onSuccess(res.json, res.headers),
           (res: ResponseWrapper) => this.onError(res.json)
       );
   }


ngOnInit() {
       this.searchTerms
       .debounceTime(300)
       .distinctUntilChanged()
       .switchMap((value: string) => {
           this.appRequestParams.appName = value;
           this.fetchApps();
       });
   }

.switchMap()在线错误:

代码语言:javascript
复制
Argument of type '(value: string) => void' is not assignable to parameter of type '(value: string, index: number) => ObservableInput<{}>'.
  Type 'void' is not assignable to type 'ObservableInput<{}>'.
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-06-05 08:59:08

代码的相关部分没有问题。问题是,你不能给switchMap打电话,让他返回另一个可以观察到的地方。

SwitchMap基本上将可观察到的最后发出的值转换为另一个可观察的值,从而提供了在动态http请求中自动取消请求的额外能力。

尝试以下几点:

代码语言:javascript
复制
private searchTerms = new Subject<string>();

search(value: string): void {
       this.searchTerms.next(value);
   }


fetchApps() {
       this.appService.query({
           appName: this.appRequestParams.appName ? this.appRequestParams.appName : null,
       });
   }


ngOnInit() {
       this.searchTerms
       .debounceTime(300)
       .distinctUntilChanged()
       .switchMap((value: string) => {
           this.appRequestParams.appName = value;
           return this.fetchApps();
       }).subscribe(
           (res: ResponseWrapper) => this.onSuccess(res.json, res.headers),
           (res: ResponseWrapper) => this.onError(res.json)
       );
   }

一个典型的示例与ActivatedRoute中的路由参数相关联。请考虑以下几点:

代码语言:javascript
复制
  @Injectable()
  export class FooService{
    ..
    getFooById(id:string): Observable<FooInterface>{
        return this.http.get('endpoint/${id}')
         .map(res=>res.json())
         .catch(_throw(error));
    }
  }

现在我们导航到类似根/foo/10980312这样的内容,其中最后一部分在路由中定义为:id

代码语言:javascript
复制
@Component({...})
class FooPreviewComponent{
  data: FooInterface;
  constructor(
    private _route: ActivatedRoute, 
    private _service: FooService) {
     this._route.params
        .switchMap(params=>
          this._service.getFooById(params.id))//switchMap return type is Observable<FooInterface> because of the definition of getFooById
        .subscribe(fooElement => this.data); //intellisense will detect the type of fooElement as FooInterface because of the return type of switchmap
  }
}

在处理http时,如果我们现在导航到root/foo/1312313,则会自动取消先前的请求。

switchMap还有其他的应用程序,但它需要对内部/外部可观察性有一定的了解,也需要了解它的一些内部结构。

您的解决方案效率低下,因为您订阅的是已取消的输入值和由它们触发的http响应,但是当您真的只想订阅http响应时,您对第一个不做任何操作。因此,您可以通过正确的方式使用switchMap来保存其中的一个订阅。

票数 4
EN

Stack Overflow用户

发布于 2017-06-05 11:09:14

最后我用了这个,效果很好。

代码语言:javascript
复制
   this.searchTerms
   .debounceTime(300)
   .distinctUntilChanged()
   .switchMap(
    (term) => {
        console.log('Term:' + term);
        this.appRequestParams.appName = term;
        this.fetchApps();
        return term;
    })
    .subscribe();
}
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44363674

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档