Как сделать так, чтобы обработчики запускались последовательно в повторном кадре?
Начиная с этих двух обработчиков, которые заботятся о получении информации о текущем пользователе:
(re-frame/register-handler
:got-user
(fn [db [_ user]]
(assoc db :user user)))
(re-frame/register-handler
:get-user
(fn [db [_]]
(ajax/GET "/user"
{:handler #(re-frame/dispatch [:got-user %1])})
db))
на одной странице я хочу отобразить список друзей, но проблема в том, что это зависит от пользователя, которого выбирают в первую очередь:
(re-frame/register-handler
:get-friends
(fn [db [_]]
(when (nil? (:user db))
(re-frame/dispatch [:get-user]))
; Here's the problem, as I need to way for get-users and got-users to run.
(ajax/GET (str "/users/" (get-in db [:user :id]))
{:handler #(re-frame/dispatch [:got-friends %1])})
db))
Как мне структурировать этот код?
2 ответа
Во-первых, документация специально предупреждает против создания обработчиков с побочными эффектами (т. Е. Отправки событий от обработчиков событий). Во-вторых, не пытайтесь повторно использовать обработчики событий, но реорганизуйте повторно используемые части в вспомогательные функции. Используя re-frame-http-fx, я бы написал что-то вроде этого:
(reg-event-fx
:get-friends
[trim-v]
(fn
[{db :db} [_]]
{:http-xhrio (if (:user db)
{:method :get
:uri (str "/users/" (get-in db [:user :id]))
:on-success [:got-friends]
:on-failure [:get-friends-load-failed]}
{:method :get
:uri "/user"
:on-success [:get-friends-for-user]
:on-failure [:get-friends-user-load-failed]})
:db db}
))
Затем get-friends-for-user сначала сохранит полученного пользователя и начнет извлекать друзей.
Вдохновившись статьей о решении проблемы с загрузкой процессора, я заставил get-friends звонить сам, пока пользователь равен нулю, но чтобы избежать отправки большого количества запросов на сервер, он также добавляет флаг о запрашиваемом пользователе:
(re-frame/register-handler
:get-friends
(fn [db [_ user-requested]]
(if-let [user (:user db)]
(ajax/GET (str "/users/" (get-in db [:user :id]))
{:handler #(re-frame/dispatch [:got-friends %1])})
(do
(when (not user-requested)
(re-frame/dispatch [:get-user]))
(re-frame/dispatch [:get-friends true])))
db))
Это работает, но на локальной машине ему удается вызывать себя 9 раз или около того, пока пользователь-пользователь не установит пользователя. Не уверен, если это будет проблемой или нет, и я открыт для других решений, если они существуют.