Два ответа
Нет. Подписаться с дублем не всегда синхронно. То, что делает наблюдаемую асинхронность / синхронизацию, это производитель выданных значений, а не операторы в потоке. Теперь, если в какой-то момент вы не использовали take(1)
или не отписались от Observable, это не проблема синхронности, а утечка памяти. take(1)
важен, но не из-за проблем синхронности.
В вашем случае вы используете функцию для создания и подписки на наблюдаемую информацию, которая получает самые последние данные из хранилища, что по сути является BehaviorSubject в том смысле, что она всегда возвращает самую последнюю значения на подписку, а затем обновления после этого. Это синхронное действие, и я не вижу причин, по которым оно не всегда будет работать.
Это можно проверить, создав простую синхронную Observable, изменив значение, а затем немедленно выйдя из него.
https://stackblitz.com/edit/rxjs-ujs6u9
Однако вы можете упростить это и вернуть сам Observable вместо того, чтобы обернуть его в функцию:
csvHref$ = this.store$.select(MissionsStoreSelectors.selectedRoute).pipe(
take(1),
map(route => {
if (!route) {
return null;
}
const csv = this.csvManipulatorService.generateCSVFromJSON({
filename: route.routeId,
data: route.waypoints,
columns : ['id', 'position', 'rotation']
});
return this.domSanitizer.bypassSecurityTrustUrl(`data:text/csv,${encodeURIComponent(csv)}`);
})
)
И затем вместо того, чтобы вызывать его как функцию, вы просто подписываетесь на него, чтобы получить значение.
csvHref$.subscribe(href => doSomethingWithHref(href));
Исходя из вашего использования, это может оказаться невозможным, но вы должны думать о Observables как о функциях уже.
Я рекомендую https://medium.com/@benlesh/learning-observable-by-building-observable-d5da57405d87 как хорошее чтение.