I have a singleton service for app settings
class Setting {
get foo() {
return storage.get('foo');
}
set foo(val)
storage.set('foo', val);
}
}
that is bound in components' views as setting.foo.
Because storage calls may be costly and because it may be asynchronous, I would prefer to replace getter/setter with RxJS subject that could update and read storage whenever needed.
So I'm refactoring it to
class Setting {
constructor() {
this.fooSubject = new ReplaySubject(1);
fooSubject.subscribe((val) => {
storage.set('foo', val);
});
this.foo$ = this.fooSubject
.map(() => storage.get('foo'))
.publishReplay(1).refCount();
}
and using it like setting.foo$ | async and setting.fooSubject.next(newFoo). It looks like costly storage.get calls are cached now.
There are two problems.
The first one is that both fooSubject subject and foo$ observable should be publicly available to make this work, while a subject was chosen because it is supposed to be both an observable and an observer.
Can foo$ be made to be a single Subject property of Setting service, so it could be subscribed with subscribe(...) and updated with next(...)?
The second one is that the code is still synchronous.
How can this case be treated for storage.get and storage.set that return promises?