Если мы посмотрим на def addCondition(cond: Page => CallbackTo[Boolean])(condUnmet: Page => Option[Action[Page]]): Rule[Page]
, то увидим, что для этого требуется CallbackTo[Boolean]
. Из-за природы JS env теперь есть путь от Future[A]
до A
. Хотя это не ограничение самого scalajs-реагирует, это унаследованная реальность, которая повлияет на ваш код scalajs-реагировать; как показывает эта таблица в документе , нет способа перейти от CallbackTo[Future[Boolean]]
к CallbackTo[Boolean]
.
Это ограничение на уровне типов действительно очень полезно для взаимодействия с пользователем. Маршрутизатор является синхронным, он должен определить, как немедленно отрисовывать маршруты и изменения маршрута. Если бы ему было разрешено быть асинхронным и каким-либо образом поддерживать Future
s, то пользователь испытал бы заметные (и потенциально огромные) задержки без какой-либо визуальной обратной связи или средств прерывания.
«Правильный путь» для решения этой проблемы - использовать модель, охватывающую асинхронное состояние. Вот что я бы сделал:
- Создайте
AsyncState[E, A]
ADT с кейсами: Empty
, AwaitingResponse
, Loaded(value: A)
, Failed(error: E)
.
(Вы можете дополнительно обогатить их, если хотите, например, loadTime on Loaded
, повторите обратный вызов на Failed
, время запуска на AwaitingResponse
и т. д.)
- Имейте экземпляр
AsyncState[Boolean]
в вашем (локальном / клиентском) состоянии.
- При желании можно запустить асинхронную загрузку при запуске страницы.
- Пусть маршрутизатор передаст свое значение компоненту и / или проверит его значение.
(Маршрутизатор не будет знать значение, потому что оно динамическое, используйте Callback
в качестве для понимания соединяйте вещи и удовлетворяйте типам.)
- В зависимости от значения
AsyncState[Boolean]
визуализируйте что-то значимое для пользователя. Если это AwaitingResponse
, покажите маленький счетчик; если это не удалось, выведите ошибку и, возможно, кнопку повтора.
(Следует также отметить, что AsyncState[Boolean]
на самом деле не должно быть Boolean
, поскольку это не очень описательно или не соответствует действительности. Возможно, это будет что-то более значимое, например AsyncState[UserAccess]
или что-то в этом роде.)
Надеюсь, это поможет! Удачи!