RxJS:有条件地重复AJAX并返回上一个结果的响应

时间:2019-01-24 13:13:50

标签: rxjs

我们有一个API,该API将以布尔值hasMoretoken进行响应。如果hasMoretrue,我们可以使用该token进行另一个API调用以获取下一组结果。需要重复此过程,直到hasMorefalse。然后,需要将整个结果列表作为一个列表发出,并且需要完成可观察项。

我设法使用BehaviorSubject实现了这一点:

function getAll() {
  const subject = new BehaviorSubject(undefined);

  const obs = subject
    .asObservable()
    .pipe(
      flatMap(token => getRes(token)
        .pipe(
          tap(result => result.hasMore ? subject.next(result.token) : subject.complete())
        )
      ),
      map(result => result.items),
      reduce((acc, items) => acc.concat(items), [])
    );

  return obs;
}

(其中getRes()返回一个可观察到的对象,该对象使用提供的令牌进行API调用,并以JSON形式发出API响应主体)

请参见https://rxviz.com/v/7J245RDo

但是,我想知道是否有一种不使用BehaviorSubject的纯粹可观察的方式来做到这一点。我尝试使用repeatWhen,但无法弄清楚如何更改输入数据并映射到响应数据。

1 个答案:

答案 0 :(得分:1)

您要查找的内容称为expand()运算符。基本上,它允许您根据收到的输入进行递归

doRequest()
  .expand((resultPage) => resultPage.hasMore ? doRequest(resultPage.token) : Observable.empty())
  .subscribe((page) => console.log(page));

每页结果都通过expand()运算符发送到您的订阅。在展开中,您可以根据需要递归到下一页,或者返回一个空的Observable表示递归结束。