So I've got this observable pipe where I need to do an operation once at the beginning of the subscription, just like you can use finalize()
to do an operation once at the end of a subscription
So this is what I started with, unfortunately it will do the startup once per each next()
call that is made towards the subject.
const notificationSubject = new BehaviorSubject<Notification | undefined>(undefined);
const notifications$ = this.notificationSubject.pipe(
tap(() => startup()),
filter(isValueDefined),
finalize(() => shutdown())
);
notifications$.subscribe(noti => foo(noti));
notifications$.subscribe(noti => bar(noti));
Then we got this variant:
let isStartedUp = false;
const internalStartup = () => {
if(!isStartedUp){
isStartedUp = true;
startup();
}
}
const notifications$ = notificationSubject.pipe(
tap(() => internalStartup()),
filter(isValueDefined),
finalize(() => shutdown())
);
notifications$.subscribe(noti => foo(noti));
notifications$.subscribe(noti => bar(noti));
... which does it's job however it does it a little too well as now the startup is only made once ever (and only on the first subscription) instead of once per subscription that is created.
I imagine there being something along the lines of this but I haven't found it.
const notifications$ = notificationSubject.pipe(
initialize(() => startup()),
finalize(() => shutdown())
);
You can usedefer
to execute some code on every subscribe.
export function initialize<T>(initializer: () => void): MonoTypeOperatorFunction<T> {
return (source: Observable<T>) => defer(() => {
initializer();
return source;
});
}
const notifications$ = notificationSubject.pipe(
initialize(() => startup()),
finalize(() => shutdown())
);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.