RxJS Observable with Subject,通过计时器和combineLatest进行轮询不会触发

时间:2017-02-21 21:06:42

标签: angular typescript rxjs polling rxjs5

我写了一个函数来对一个也可以进行分页的API进行轮询。因此,使用Subject Observable完成分页,并使用计时器方法完成轮询(我也尝试使用相同结果的间隔)。

这是我的代码:

  getItems(pagination: Subject<Pagination>): Observable<ListResult<Item>> {
    let params: URLSearchParams = new URLSearchParams();

    return Observable
      .timer(0, 5000)
      .combineLatest(
        pagination,
        (timer, pagination) => pagination
      )
      .startWith({offset: 0, limit: 3})
      .switchMap(pagination => {
        params.set('skip', pagination.offset.toString());
        params.set('limit', pagination.limit.toString());
        return this.authHttp.get(`${environment.apiBase}/items`, {search: params})
      })
      .map(response => response.json() as ListResult<Item>)
      .catch(this.handleError);
  }

预期的行为是: HTTP请求每5秒触发一次,当用户更改页面时。

这是发生的事情: 第一个HTTP请求被触发,但是没有其他请求被发送到服务器UNTIL使用分页。 在第一次使用分页后,轮询也开始工作。

这是我第一次使用Observables,所以我很确定我错过了什么,但我无法看到它可能是什么。

我也试过这种方法(也许它在startWith中缺少计时器计数器),但它并没有改变任何东西。

[...]
  .combineLatest(
    pagination
  )
  .startWith([0, {offset: 0, limit: 3}])
[...]

2 个答案:

答案 0 :(得分:2)

combineLatest()运算符要求所有源Observable都至少发出一个项目。

您的演示只提出一个请求,因为您正在使用.startWith()combineLatest()永远不会发出,因为paginationSubject,并且它可能永远不会发出任何项目。

所以一个选择就是移动.startWith()

.combineLatest(
  pagination.startWith({offset: 0, limit: 3}),
  (timer, pagination) => pagination
)

但也许这对你没有多大帮助,因为你忽略了来自timer()的所有项目而你只使用了pagination。所以也许你可以只使用merge()来刷新其中一个来源的列表。然后timer()独立地增加偏移量。

Observable
  .timer(0, 1000)
  .map(i => { return {offset: i*3, limit: 3}})
  .merge(pagination.startWith({offset: 0, limit: 3}))
  .switchMap(pagination => {
    return Observable.of(pagination).delay(200)
  })
  .subscribe(val => console.log(val));

答案 1 :(得分:-1)

确保您遵循以下步骤

创建onservable数据

您有一个可观察的可测量数据,并且您正在按observable.next(value);

推送数据

在主题或behourSubject

中获取数据

如果您想获取数据,则要声明主题类型变量并通过订阅来访问它。

private val: Subject = YourObservable;
private uiValue: string;

val.sunscribe((val) => {
   uiVal = val;
});

现在,您可以在任何位置使用uiVal进行更新。

你可以通过console.log来确保一切正常工作

来分别测试两个部分