Наблюдаемый ли берутся из ngrx синхронно? - PullRequest
0 голосов
/ 21 июня 2019

У меня есть следующая функция:

Возьмите значение из моего магазина => Преобразовать его в CSV => Создать ссылку для скачивания

  downloadCSV() {
    let href;
    this.store$.select(MissionsStoreSelectors.selectedRoute).pipe(take(1)).subscribe((route) => {
      if (route) {
        const csv = this.csvManipulatorService.generateCSVFromJSON({filename: route.routeId, data: route.waypoints, columns : ['id', 'position', 'rotation']});
        href = this.domSanitizer.bypassSecurityTrustUrl('data:text/csv,' + encodeURIComponent(csv));
      }
    });
    return href;
  }

(не заботьтесь о том, что нет охраны, упрощенно)

Я думал, что подписка не была синхронной. Но из этого принятого ответа:

Как получить текущее значение объекта State с помощью @ ngrx / store?

похоже, что это не так.

Мой вопрос: это сработает в 100% случаев? Всегда ли подписка с дублем всегда синхронна?

1 Ответ

1 голос
/ 21 июня 2019

Два ответа

  1. Нет. Подписаться с дублем не всегда синхронно. То, что делает наблюдаемую асинхронность / синхронизацию, это производитель выданных значений, а не операторы в потоке. Теперь, если в какой-то момент вы не использовали take(1) или не отписались от Observable, это не проблема синхронности, а утечка памяти. take(1) важен, но не из-за проблем синхронности.

  2. В вашем случае вы используете функцию для создания и подписки на наблюдаемую информацию, которая получает самые последние данные из хранилища, что по сути является 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 как хорошее чтение.

...