Итак, здесь есть пара вещей. Во-первых, у вашей наблюдаемой цепочки есть проблемы, вы, как правило, хотите оставить вещи ВНУТРИ наблюдаемой последовательности, и вы хотите сделать это повторяемым образом. Я мог бы переписать это так:
interface Config {
apiKey: string
checkUrl: string
}
@Injectable()
export class MyService {
private configSource = new ReplaySubject<Config>(1) // stores config
private setApiInformation() { // private method to load config, call once
this.systemConfigurationService.getSystemConfiguration().subscribe(this.configSource)
}
// all calls go through here to ensure config is ready
private awaitConfig<T>(action$: (config: Config) => Observable<T>) {
return this.configSource.pipe(
first(),
switchMap(client => action$(client)) // switchMap subscribes to inner observables
)
}
constructor(private systemConfigurationService: SystemConfigurationService) {
this.setApiInformation() // call once here
}
checkServerData(data: RequestParameters): Observable<ServerResponseData> {
return this.awaitConfig(config => { // use config from here
let httpOptions = { headers: new HttpHeaders({ "serverApiKey" : config.apiKey }) };
return this.httpClient.put<ServerResponseData>(config.checkUrl, request, this.httpOptions);
}));
}
}
Это хороший способ решить эту проблему для всех вызовов, требующих чего-то асинхронного, теоретически вы могли бы написать базовый сервис, из которого остальные расширяют или, предпочтительно, внедрять и использовать чтобы сделать их вызовы, НО, если это вещь всего приложения, вам лучше использовать APP_INITIALIZER, чтобы убедиться, что что-то сделано (например, загрузка конфигурации) до запуска остальной части приложения.