Observable 无法在 Doc reader 中使用异步等待函数

Observable not working with async await function in Doc reader

我正在尝试像下面这样在 Observable 上等待:

    documentXFDFRetriever: async () => {
            const rows = await this.annotationsService.getAnnotations(this.userService.getCurrentDocumentId()).toPromise();
            console.log(rows);
            return rows.map(row => row.annotationNode);
          }

我的服务功能:

    public getAnnotations(docId): Observable<Annotation[]> {
        const userId = this.userService.getCurrentUserId();
        const annotationsRef = collection(this.firestore, `annotations/${docId}/${userId}`);
        return collectionData(annotationsRef) as Observable<Annotation[]>;
    }

但它不能 return 行 documentXFDFRetriever 函数。

我确定 return observable 中缺少某些东西。

谁能帮我解决这个问题?

这是因为 observable toPromise 辅助函数在实际解析自身之前等待 observable 完成(或出错)。

因此,要解决此问题,您可以 takeObservable 发出的第一个值来完成它,然后再调用 toPromise 函数,如下所示:

// import { take } from 'rxjs/operators';

// by using `take` operator, the converted observable will be completed after emitting one value, then being converted to `Promise`.
const rows = await this.annotationsService.getAnnotations(this.userService.getCurrentDocumentId()).pipe(take(1)).toPromise();

OR 如果你使用的是 RxJS 7,你可以使用 firstValueFrom 辅助函数而不是 toPormise 一个,来实现同样的事情。

更多信息: https://rxjs.dev/deprecations/to-promise

具有讽刺意味的是,正是这种混淆正是 RxJS 弃用的原因 toPromise。如果您使用的是较新版本的 RxJS,我会推荐 firstValueFromlastValueFrom

如果您使用的是旧版本的 RxJS,您可以使用 take(1) 或 first() 来确保可观察对象完成并解析承诺。

documentXFDFRetriever: () => this.annotationsService.getAnnotations(
  this.userService.getCurrentDocumentId()
).pipe(
  map(rows => rows.map(row => row.annotationNode)),
  first() // Complete Observable after first emission
).toPromise();