最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 结合rxjs,实现高效http请求

    正文概述 掘金(leemove666)   2020-11-24   823

    结合rxjs,实现高效http请求

    在项目中经常会碰到这样的需求,用户在输入框输入数据,需要实时调用后台api,根据结果对输入进行重复校验,或者搜索。

    结合rxjs,实现高效http请求

    这里我们以github的用户搜索api做示例。

    @Component({
      template: `
        <input (keyup)="search($event.target.value)">
        <ul>
          <li *ngFor="let user of userList">
            {{user.login}}
            <img [src]="user.avatar_url">
          </li>
    		</ul>
      `
    })
    export class HttpRequestComponent {
      constructor(private httpClient: HttpClient) { }
      
      userList: any[] = [];
      //进行搜索 并且渲染到当前页面
      search(name: string): void {
        this.sendSearchRequest(name)
          .subscribe(res => {
            this.userList = res.items;
          });
      }
    	// 发送搜索请求
      sendSearchRequest(name): Observable<{items: any[]}> {
        return this.httpClient.get<{items: any[]}>('https://api.github.com/search/users?', {
          params: {
            q: name
          }
        });
      }
    }
    

    以上代码足以完成需求,但是同时有以下几种隐患。

    1. 请求效率比较低,如果我输出netease那么因为输入的变化,n,ne, net...netease会合计发起共7次请求。其实只要最后一次netease的结果。
    2. 多次请求的结果响应时间并不可控,从而渲染结果不可控。假设第一条n的搜索请求响应耗时10s,而其他请求包含netease搜索都只需要1s,那页面最终的渲染结果为n的搜索结果,显然这样是不正确的。

    解决上述问题需要用到几个操作符:

    export class HttpRequestComponent implements OnInit {
    
      constructor(private httpClient: HttpClient) { }
    
      userList: any[] = [];
    
      // 搜索subject
      private onSearch$: Subject<string> = new Subject();
    
      search(name: string): void {
        // 每次输入都生产一个值
        this.onSearch$.next(name);
      }
    
      private sendSearchRequest(name): Observable<{items: any[]}> {
        return this.httpClient.get<{items: any[]}>('https://api.github.com/search/users?', {
          params: {
            q: name
          }
        });
      }
    
      ngOnInit(): void {
        // 初始化的时候订阅search$,更新页面搜索结果。
        this.onSearch$.asObservable()
          .pipe(
          	// 注意先后顺序
            // 防抖
            debounceTime(1000),
            // 变化才会请求
            distinctUntilChanged(),
            // 映射为新的Observable
            switchMap(name => this.sendSearchRequest(name))
          )
          .subscribe(res => {
            this.userList = res.items;
          });
      }
    }
    
    • Subject 有着双重特性,它同时拥有 Observer 和 Observable 的行为。(多用于组件间通信场景)

      // 发送值
      subject.next( 2 )
      // 订阅值
      const subscription = subject.subscribe( (value) => console.log(value) )
      
    • debounceTime前端常见的防抖策略,在一定时间内,只保留最后一次的值。

      ​ 当用户在1000ms内连续输入的时候,我们只针对最后一次输入做请求,大大提升了请求效率。

    • distinctUntilChanged只有值发生变化才会更新。只有内容变化才会触发请求。

      ​ 部分浏览器输入中文可能会产生输入值不变,但是重复触发输入事件的问题

    • switchMap 有点类似于Promise。实际作用为完成前一个observable,映射成一个新的observable。

      ​ 实际在angular中,当在上述的重复请求业务场景中,例如搜索,翻页等等,当前一条请求未完成,而后一条请求已经发出,那么此操作符会导致前一条请求被取消,从而保证了请求以及结果的顺序。


    起源地下载网 » 结合rxjs,实现高效http请求

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元