如何恢复订阅才能等待订阅完成?
让SettingService
可以从服务器获取一次设置,然后将其缓存。它为其使用者提供了get(key): Setting
方法,并确保仅存在具有相同键的设置的单个实例。这有两个含义:
到目前为止我所拥有的:
export class SettingService {
private settings: Setting[] = [];
private settingSubscription: Subscription;
private settingLoaded: Boolean = false;
constructor(private http: HttpClient) {
this.initSettings();
}
private initSettings() {
this.settingSubscription = this.http.get<Setting[]>('api/Setting').subscribe(s => {
this.settings = s;
this.settingLoaded = true;
});
}
get(key: string): Setting {
if (!this.settingLoaded) {
//TODO: wait for settingSubscription to finish
}
return this.resolveSetting(key);
}
private resolveSetting(key: String) {
//uses this.settings to retreive the setting
}
}
这个问题与Wait on RxJs.Subscriptions to finish before resuming非常相似,除了我必须确保异步方法只执行一次。
答案 0 :(得分:4)
如果您遵循“反应性口头禅”,您的问题将得到解决:
请参阅The introduction to Reactive Programming you've been missing以了解其含义。
牢记这一想法,Settings
服务可以按以下方式完成:
const { timer } = rxjs; // = require("rxjs")
const { map, mapTo, shareReplay } = rxjs.operators; // = require("rxjs/operators")
// emulate making ajax request
function loadSettings() {
console.log('request to load settings ...');
return timer(2000).pipe(
mapTo({
a: 'a-value',
b: 'b-value'
})
);
}
// Settings service
const settings$ = loadSettings().pipe(
shareReplay(1) // cache result
);
const get = key => settings$.pipe(
map(s => s[key] || 'default')
);
// usage example
get('a').subscribe(v => console.log("result for a: ", v));
setTimeout(
() => get('unknown').subscribe(v => console.log("result for unknown:", v)),
5000
);
<script src="https://unpkg.com/rxjs@6.3.3/bundles/rxjs.umd.min.js"></script>
回顾一下: