在forkjoin TS中使用await

时间:2018-12-11 13:23:57

标签: angular typescript asynchronous

我正在尝试根据旧结果检索新结果。因此,当我的主导调用中的特定参数是X时,它应该调用另一个函数,但是我当前的问题是范围继续运行,这会导致新参数丢失。

代码如下:

export class DashboardGuard implements CanActivate { 


 public canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> { 
    this.logger.info(DashboardGuard::canActivate());
    return Observable.create((subscribe: Subscriber<boolean>): void => { 


    Observable.forkJoin(
                this.mapSettingsService.fetch(),
                this.userSettingsService.fetch(),
                this.mapFenceService.fetch(),
                this.markersMotesService.fetch(),
                this.markersStaticsService.fetch()
            ).subscribe((result: [MapSettings, UserSettings, MapFenceGroup[], MarkersMotes, MarkersStatics]): void => {

                // Fetch loaded motes and statics
                const mapSettings: MapSettings = result[0];
                const userSettings: UserSettings = result[1];
                const mapFenceGroups: MapFenceGroup[] = result[2];
                let markersMotes: MarkersMotes = result[3];
                const markerStatics: MarkersStatics = result[4];

                for (let i in markersMotes.items) {
                    if (markersMotes.items[i].longitude === 0 || markersMotes.items[i].latitude === 0) {
                        // Here I want to call another fetch with the data from the previous fetches, but the program scope
                        // should wait until it finished those fetches.
                        //  Example of fetch:
                        Observable.forkJoin(
                            this.markersMotesService.newfetch(markersMotes.items[i].macAddress),
                        ).subscribe((result: [MarkersNolocations]): void => {
                            const newResult: MarkersNolocations = result[0];
                            if (newResult.missedCounter > 0) {
                                markersMotes.items[i].latitude = 10;
                                markersMotes.items[i].longitude = 10;
                            }
                        });

                    }
                }
})

我知道forkjoin是检索所有呼叫的绝佳选择,但是里面的呼叫呢?

任何帮助将不胜感激!

问候,

布拉姆

1 个答案:

答案 0 :(得分:0)

通常应避免嵌套订阅。首选链接运算符。在这种情况下,您想使用开关映射将一个可观察到的输出通过管道传递到另一个可观察到的输入。

https://www.learnrxjs.io/operators/transformation/switchmap.html

我修改了您的代码以使用switchMap,以使您有所了解。我不知道您的MarkerMotes类是什么样子,因此怀疑它是否可以正常工作,但应该可以给您一个提示。

let itemsNeedingLocation: SomeClassHere[] = [];
Observable.forkJoin(
                this.mapSettingsService.fetch(),
                this.userSettingsService.fetch(),
                this.mapFenceService.fetch(),
                this.markersMotesService.fetch(),
                this.markersStaticsService.fetch()
            ).switchMap((result: [MapSettings, UserSettings, MapFenceGroup[], MarkersMotes, MarkersStatics]): void => {

                // Fetch loaded motes and statics
                const mapSettings: MapSettings = result[0];
                const userSettings: UserSettings = result[1];
                const mapFenceGroups: MapFenceGroup[] = result[2];
                let markersMotes: MarkersMotes = result[3];
                const markerStatics: MarkersStatics = result[4];
                let obs: Observable[] = [];

                for (let i in markersMotes.items) {
                    if (markersMotes.items[i].longitude === 0 || markersMotes.items[i].latitude === 0) {
                        itemsNeedingLocation.push(markersMotes.items[i]);
                        obs.push(this.markersMotesService.newfetch(markersMotes.items[i].macAddress));
                    }
                }
                return Observable.forkJoin(obs);
            }).subscribe((result: [MarkersNolocations]): void => {
                itemsNeedingLocation.forEach((item, index) => {
                    if (result[index].missedCounter > 0) {
                        item.latitude = 10;
                        item.longitude = 10;
                    }
                });
            });