Асинхронная обработка наблюдаемых - PullRequest
0 голосов
/ 18 июня 2020

Я довольно новичок в rx js и реактивном программировании в целом, и у меня довольно много серой области, окружающей асинхронную c обработку наблюдаемых.

У меня есть прямой сценарий с маршрутизация пользователя в мое веб-приложение после того, как пользователь нажимает кнопку входа в систему.

Процесс выглядит следующим образом: Шаг 1: Пользователь нажимает кнопку «Войти». Шаг 2: В функции обработчика для кнопки входа в систему - onSuccess, я получаю данные о состоянии профиля, обновленные для текущего пользователя. Шаг 3: Перейдите на страницу профиля или главную страницу панели инструментов в зависимости от погоды, обновляются ли данные или нет.

Ниже мой LoginHandler:

handleLogin = async (result: NetworkResult<AccessTokenResult>) => {
    performOnNetworkResult(result, {
      onSuccess:  () => {
         this.profileService.isdetailupdated //gets the state of details from profile service
          .pipe(
            takeUntil(this.ngUnsubscribe),
          )
          .subscribe(
             details=> {
               //routing based on boolean details
               if (details !== null && details) {
                  this.router.navigate(['/dashboard']);
               } else if (details !== null && !details ) {
                  this.router.navigate(['/profile']);
               }
             }
          );
    });
  };

А вот краткий снимок кода сервиса, который обновляет isdetailsupdated

 fetchProfile = () => {
      return this.profileApiService.getProfile().pipe(
        tap(profileResult =>
          performOnNetworkResult(profileResult, {
            onSuccess: () => {
              this.profileValue = profileResult.value; //this one resolves a while after my login on success is executed
              if (this.profileValue !== null && this.profileValue.phoneNumber !== null && this.profileValue.address !== null) {
                this.isdetailupdated.next(true);
              } else {
                this.isdetailupdated.next(false);
              }

              }
        }
  }))

Первоначально у меня был isdetailupdated из profileService, настроенный как observable , а мой раздел подписки вообще не запускался, потому что для profileservice существует задержка для разрешения isdetailsUpdated, и как только он разрешен, моя наблюдаемая подписка не вызывается асинхронно. (почему!?)

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

Я решил эту проблему, преобразовав profileService.isdetailupdated в ReplaySubject . С ReplaySubject подписчик на самом деле ждет, пока он получит начальное значение, и моя маршрутизация работает должным образом (я не мог использовать BehaviourSubject по той причине, что у него будет начальное значение, вызывающее мои logi c в случае неудачи, ReplaySubject не требует начального значения, и в моем случае я сделал его для обновления только после того, как мой profileService разрешит состояние detailsToBeUpdated)

All Cool, задача решена. Вот только мне сложно осмыслить все это в голове. Это казалось очень распространенным вариантом использования, и я действительно не уверен, слишком ли много делаю с ReplaySubject et c. Итак, вот мои вопросы:

1. Почему подписка наблюдаемого объекта не вызывается асинхронно после того, как наблюдаемый объект имеет новое значение? 2. Если нам нужно использовать ReplaySubjects для асинхронной обработки наблюдаемых, почему это так неясно в документации? Learnrx js определяет ReplaySubjects следующим образом:

ReplaySubject - выдает указанное количество последних переданных значений (повтор) новому подписчику

, что на самом деле не поучительно для поведения, для которого я его использую.

3. Есть ли более элегантный способ решения моего сценария, который представляет собой функцию обработчика входа в систему, ожидающую разрешения наблюдаемого перед маршрутизацией ?

...