RxJS from() 运算符永远不会完成

RxJS from() operator never completes

我正在尝试在共享点列表中执行元数据更新。在我的组件中:

this.datasetService.updateMetadata(oldDatasetName, projectMetadata).subscribe(() => {
   this.onCompleted('DownloadDataset.Updated');
}, error => this.onError(error, 'DownloadDataset.UpdateError'));

然后在服务中:

updateMetadata(oldDatasetName: string, metadata: ProjectDatasetModel): Observable<boolean[]> {
    const filterString = `DataSetName eq '${oldDatasetName}'`;
    return this.graphService.getFilteredListItems(ResourceNames.PROJECT_DATASET_LIST_NAME, filterString).pipe(switchMap(items => from(items).pipe(mergeMap(item => {
        const updated = { ...item, DataSetName: metadata.datasetName, DataSetDescription: metadata.datasetDescription };
        return this.graphService.updateListItem(ResourceNames.PROJECT_DATASET_LIST_NAME, updated.Id, updated);
    }), toArray(), tap(() => console.log("Update completed")))));
}

图表服务:

public getFilteredListItems(listTitle: string, filter: string): Observable<any[]> {
    const sub$ = new Subject<any[]>();
    this.configureSharepointToken().subscribe(configured => {
        sp.web.lists.getByTitle(listTitle).items.filter(filter).get().then((items: any[]) => {
            sub$.next(items);
        });
    });
    return sub$.asObservable();
}

public updateListItem(listTitle: string, itemId: number, listItem: any): Observable<boolean> {
    const sub$ = new Subject<boolean>();
    this.configureSharepointToken().subscribe(configured => {
        sp.web.lists.getByTitle(listTitle).items.getById(itemId).update(listItem)
            .then(iar => {
                sub$.next(true);
            });
    });

    return sub$.asObservable();
}

我的问题是,如果有要更新的项目,更新确实会发生,我可以使用新的元数据,但 tap() 永远不会发生。有什么建议吗?

getFilteredListItemsupdateListItem 中,您是 return 一个永远无法完成的主题。 toArray 运算符在主题关闭之前不会执行。

创建主题并 return 处理它们的整个过程是多余的。如果 configureSharepointToken return 是一个可观察对象,那么只需 switchMap 从这些流到新的源。超级有趣的事实:任何接受 observables 的操作符都会在 promises 上工作。这就是为什么 get 方法的结果可以传递给 switchMap.

public getFilteredListItems(listTitle: string, filter: string): Observable<any[]> {
  return this.configureSharepointToken().pipe(
    switchMap(() =>  sp.web.lists.getByTitle(listTitle).items.filter(filter).get())
  );
}

public updateListItem(listTitle: string, itemId: number, listItem: any): Observable<boolean> {
  return this.configureSharepointToken().pipe(
    switchMap(() => sp.web.lists.getByTitle(listTitle).items.getById(itemId).update(listItem)),
    mapTo(true)
  );
}

请注意,可能需要在管道的开头添加 first 运算符,以防 configureSharePointToken 保持打开状态。就个人而言,它会有不止一次发射似乎很奇怪。