RxJS - 无限滚动 - 在之前未到达时发送请求

时间:2017-11-11 19:51:09

标签: javascript angular typescript rxjs reactive-programming

我对反应式编程非常陌生,这是我对RxJs的第一件事,无限滚动:

public pageByScroll$ = Observable.fromEvent(window, "scroll")
  .map(() => document.documentElement.scrollHeight - document.documentElement.scrollTop - document.documentElement.clientHeight)
  .filter(x => x < 800)
  .debounceTime(200)
  .scan(count => count + 1, 0);


handleScroll() {
  this.pageByScroll$.subscribe(
    pageToLoad => this.advertiserService
      .getAdvertisersByPage(pageToLoad)
      .subscribe(advertisers => this.advertisers = this.advertisers.concat(advertisers))
  );
};

getAdvertisersByPage(page: number): Observable<AdvertiserClass[]> {
    return this.http.get(this.advertisersUrl + '/pager/' + page)
     .map(res => {
       return res.json().map(advertiser => {
         return new AdvertiserClass(advertiser);
       });
     });
 }

我的问题来自测试数据库服务器很远,它需要1 +秒才能接收数据 如果我在没有收到新数据并且页面高度很小的情况下继续滚动,它会继续发送下一页的请求。 如果没有收到上一个请求,我怎么能让它等待发送请求呢?

2 个答案:

答案 0 :(得分:2)

Nice pageByScroll功能。

正如@pixelbits所说,基本问题是this.pageByScroll$.subscribe()应该是this.pageByScroll$.map(),但是玩弄它我注意到它也会向上滚动页面。

您可以通过记住上次看到的scrollTop来解决这个问题 请注意,如果向下,向上,向下滚动也可以。

const pageByScroll$ = Observable.fromEvent(window, "scroll")
  .map(() => document.documentElement.scrollTop)
  .scan((scrollTop, last) => scrollTop > last ? scrollTop : last, 0)
  .distinctUntilChanged()
  .map(downwardScrollTop => 
    document.documentElement.scrollHeight
       - downwardScrollTop
       - document.documentElement.clientHeight
    )
  .filter(x => x < 800)
  .debounceTime(200)
  .scan(count => count + 1, 0)

答案 1 :(得分:1)

您订阅的次数太多了。编写事件流以创建一个observable。假设,pageByScroll $按预期工作,您可以使用concatMap将Observable流附加在一起(最后一个在下一个开始之前完成,按顺序发出)。

var o= this.pageByScroll$.concatMap(t=>this.getAdvertisersByPage(t));
o.subscribe(t=> this.advertisers.concat(t));