我们有一个API,该API将以布尔值hasMore
和token
进行响应。如果hasMore
是true
,我们可以使用该token
进行另一个API调用以获取下一组结果。需要重复此过程,直到hasMore
为false
。然后,需要将整个结果列表作为一个列表发出,并且需要完成可观察项。
我设法使用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,但无法弄清楚如何更改输入数据并映射到响应数据。
答案 0 :(得分:1)
您要查找的内容称为expand()
运算符。基本上,它允许您根据收到的输入进行递归
doRequest()
.expand((resultPage) => resultPage.hasMore ? doRequest(resultPage.token) : Observable.empty())
.subscribe((page) => console.log(page));
每页结果都通过expand()运算符发送到您的订阅。在展开中,您可以根据需要递归到下一页,或者返回一个空的Observable表示递归结束。