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() 永远不会发生。有什么建议吗?
在 getFilteredListItems 和 updateListItem 中,您是 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 保持打开状态。就个人而言,它会有不止一次发射似乎很奇怪。
我正在尝试在共享点列表中执行元数据更新。在我的组件中:
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() 永远不会发生。有什么建议吗?
在 getFilteredListItems 和 updateListItem 中,您是 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 保持打开状态。就个人而言,它会有不止一次发射似乎很奇怪。