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?