无法使用RxJS 6进行递归查询并扩展运算符(Angular,Firebase和Observables)

问题描述 投票:0回答:1

我正在按照this question创建一个查询,该查询使用AngularFire从Angular 9应用程序的firebase集合中检索一个随机项。

该解决方案工作正常,除查询返回0个结果外,我得到了预期的结果。如果发生这种情况,我想重复查询更改某些参数,直到获得一项,然后才返回可观察到的可观察项,以在其他服务中进行订阅。我正在学习如何使用Observables和RxJS 6运算符,并且我认为expand运算符是我所需要的。但是,在达到期望的结果之前,我无法阻止expand退出递归循环。

这是我的代码:

random-query.service.ts

  fetchDocumentoAleatorio(coleccionPath: string): Observable<any> {
    const IdRandom = this.db.createId();
    return this.consultaAleatorio(coleccionPath, '>=', IdRandom)
      .pipe(expand((document: any) => document === null ? this.consultaAleatorio(coleccionPath, '<=', IdRandom) : EMPTY
        ), // I expect to repeat the query here changing '>=' to '<=' and using the same randomly generated Id
        map((document) => { // The recursive loop never takes place since the map operator triggers even if consultaAleatorio() returns null one single time, sending that result to the subscribers
            return publicacion.payload.doc.data();
          }
        ));
  }



consultaAleatorio(path: string, operador: any, idRandom: string): Observable<any> {
    return this.db
      .collection(path, ref => {
        let query: firebase.firestore.CollectionReference | firebase.firestore.Query = ref;
        query = query.where('random', operador, idRandom);
        query = query.orderBy('random');
        query = query.limit(1);
        return query;
      }).snapshotChanges()
      .pipe(map((arrayDatos: any) => {
        if (arrayDatos && arrayDatos.length) {
          return arrayDatos[0];
        } else {
          return null; // It indeed reaches this point if the query returns empty results
        }
      }));
  }

如果有任何其他服务使用此代码,它将以这种方式进行:

subscriber-example-service.ts

 private firebaseSubscriptions: Subscription [] = [];
  publicacionAleatoriaSubject = new Subject<IpublicacionMiniatura>();
  private publicacionAleatoria: IpublicacionMiniatura;

constructor(
    private db: AngularFirestore,
    private randomQueryService: RandomQueryService) {
  }
  fetchPublicacionAleatoria(): void {
    this.firebaseSubscriptions.push(this.randomQueryService.fetchDocumentoAleatorio('publicaciones-meta')
      .pipe(map((publicacion) => {
          return {
           //processes data
              };
            })
      )
      .subscribe((publicacionAleatoria: IpublicacionMiniatura) => {
          this.publicacionAleatoria = publicacionAleatoria;
          this.publicacionAleatoriaSubject.next(this.publicacionAleatoria);
        }
      ));

总和:

  • map运算符将触发,即使consultaAleatorio()一次返回null并将结果发送给订阅者也不会触发递归循环
  • [当我在其他服务中订阅此Observable时,除所描述的情况外,它均正常运行并按预期运行,因此,我认为问题出在我对expand运算符如何实现所需功能的误解。

提前感谢您的时间。

angular rxjs observable expand rxjs6
1个回答
0
投票

您可以如下使用retryWhen

 .pipe(map((arrayDatos: any) => {
        if (arrayDatos && arrayDatos.length) {
          return arrayDatos[0];
        } else {
          throw new Error(); //  this causes it to be catched by retryWhen
        }
      }), retryWhen(errors=>errors.pipe(delay(100))); // retry after 100ms

Stackblitz

编辑:更正了示例并增加了堆栈闪电。

© www.soinside.com 2019 - 2024. All rights reserved.