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