RXJS重复查询直到满足条件?

时间:2018-08-01 18:56:08

标签: angular rxjs

我使用的API仅返回有限数量的结果,例如100。

我想重复查询直到返回结果集为< 100,这意味着我得到了最后一个结果。

所以它会变成这样:

  1. 进行查询
  2. 结果集是否小于限制?如果是这样,请再次执行并附加结果。
  3. 一旦结果集小于限制,则发出最终结果。

4 个答案:

答案 0 :(得分:7)

您可以使用 expand 运算符来实现简单的“条件重复”行为。

仅作为示例,我将查询改为返回数字,而不是结果集。以下继续查询,直到检索到的数字小于100

const { defer, empty } = rxjs;
const { expand, toArray} = rxjs.operators;

const query$ = defer(async () =>  Math.floor(Math.random()*1000));
   
query$
  .pipe(
    expand(result => result < 100 ? empty() : query$),
    toArray()
  )
  .subscribe(console.log);
<script src="https://unpkg.com/rxjs/bundles/rxjs.umd.min.js"></script>

答案 1 :(得分:2)

 stop$: Subject = new Subject();

 query$.pipe(takeUntil(this.stop$)).subscribe( result => {
    if(result < limit) 
       this.stop$.next();
       this.stop$.complete();
     }
   else {
      process result, i.e append somewhere...
   }
 });

请注意,他是RxJs 6语法。为了提高可读性,您可以在方法中提取订阅逻辑。

在这种情况下,也许使用takeWhile会更容易:

doQuery: boolean = true;

 query$.pipe(takeWhile(()=> this.doQuery).subscribe( result => {
    if(result < limit) 
       this.doQuery = false;
     }
   else {
      process result, i.e append somewhere...
   }
 });

答案 2 :(得分:2)

You can also use RXJS Interval with TakeWhile operator. Here is the sample code

In Component:

return Observable
  .interval(250)
  .flatMap(() => this.getQueryData())
  .takeWhile(data => this.checklimit(data))
  .subscribe(result => console.log(result);

getQueryData(){
   // HTTTP API call 
}

checklimit(){
  // return true/false
}

答案 3 :(得分:0)

我们还可以使用repeatWhen运算符(与retryWhen类似,但可以完成而不是出错):

this.queryData().pipe(
    repeatWhen(obs => obs),
    filter(data => this.checkLimit()),
    take(1)
).subscribe(result => console.log(result));

注意:需要take(1)才能停止repeatWhen循环。

如果我们需要两次重试之间的延迟,可以这样做:

repeatWhen(obs => obs.pipe(delay(1000)))