Несколько способов go по этому поводу - ниже приведены три возможных решения.
Поскольку вы получаете только один результат, вы можете использовать .toPromise()
как более чистый способ преобразования потока для возврата asyn c result.
async getAssetName(i_page: IPager): string {
const assetSrc = (i_page.Player[0].$.src)
? this.storeSelector.getScene(i_page.Player[0].$.src).pipe(map(x => x.Player.$.label))
: this.storeSelector.getResource(i_page.Player[0].Data[0].Resource[0].$.resource)
.pipe(map(x => x.resource_name));
return await assetSrc.pipe(take(1)).toPromise();
}
Если вы хотите полностью избежать асинхронного c и хотите получить имя как часть построения более крупного объекта, тогда это построение может быть чисто выполнено внутри сам поток.
template: MyTemplate;
private getAssetName$(i_page: IPager): Observable<string> {
const assetSrc = (i_page.Player[0].$.src)
? this.storeSelector.getScene(i_page.Player[0].$.src).pipe(map(x => x.Player.$.label))
: this.storeSelector.getResource(i_page.Player[0].Data[0].Resource[0].$.resource)
.pipe(map(x => x.resource_name));
return assetSrc.pipe(take(1));
}
createTemplate(i_page: IPager, /* other stuff */) {
// you can skip the fork join if you're just using one observable.
forkJoin(this.getAssetName(i_page), /* other observables if necessary*/).pipe(
subscribe(([assetName, /* other results */]) => {
this.template = { assetName, /* other stuff */ };
})
);
}
Я не большой поклонник делать это таким образом. Если возможно, я бы сделал сам шаблон наблюдаемым.
Чтобы построить шаблон, я объединяю все последние изменения из всех наблюдаемых, которые необходимы для построения. При смене пейджера тема увольняется. Эта тема связана с получением assetName в combLatest с помощью switchMap. Когда результат получен, шаблон $ Observable обновляется последним результатом.
private pageChangeSubject = new Subject<IPager>();
// like forkJoin the combineLatest is only needed if multiple observables.
// getAssetName is the same method from the previous example.
template$: Observable<MyTemplate> = this.combineLatest(
this.pageChangeSubject.pipe(switchMap(x => this.getAssetName(x)))
).pipe(map(([assetName, /* ... */]) => ({ assetName, /* ... */ })));
pageChanged(page: IPager) { this.pageChangeSubject.next(page); }