Как вы управляете асинхронными операциями Store с Flux?
В разговоре Facebook о архитектуре Flux Цзин упоминает в 12:17, что диспетчер обеспечивает, чтобы никакие действия не могли быть отправлены до тех пор, пока текущее действие полностью обрабатывается магазинами.
![https://img.youtube.com/vi/nYkdrAPrdcw/0.jpg]()
Диспетчер здесь является основной частью, которая обеспечивает отсутствие каскадных эффектов; как только действие переходит в хранилище, вы не можете поместить другого в него до тех пор, пока магазины не будут полностью обработаны.
Итак, мой вопрос заключается в том, как вы правильно относитесь к длительным асинхронным операциям, которые могут быть запущены из хранилища (например, запрос Ajax или какой-либо другой внешний асинхронный API) - все, что блокирует завершение диспетчер действий (например, ожидающий решения обещания с результатом запроса Ajax) может блокировать пользовательские действия, которые пользователь может отсылать от пользователя.
Ответы
Ответ 1
В моем понимании, асинхронные действия, которые полагаются на Ajax и т.д., не должны блокировать действие от отправки всем подписчикам.
У вас будет отдельное действие для действия пользователя, например TODO_UPDATE_TEXT
в примере TodoMVC, и тот, который вызывается при возврате сервера, что-то вроде TODO_UPDATE_TEXT_COMPLETED
(или может быть просто нечто более общее, например TODO_UPDATE_COMPLETED
) содержит новую копию последних атрибутов).
В тех случаях, когда вы хотите сделать оптимистичные обновления, чтобы сразу показать пользователю последствия их изменения, вы можете немедленно обновить хранилище в ответ на действие пользователя (а затем еще раз, когда сервер вернется с авторитетными данными). Если вы хотите подождать на сервере, вы можете сохранить только хранилище в ответ на действия, вызванные сервером.
Ответ 2
Посмотрите на реализацию того, что Софи объясняет в этом примере fluxxor для работы с асинхронными данными.
Отрицательным моментом является то, что при таком подходе каждое взаимодействие с пользователем требует трех действий (триггер, успех и сбой), но, возможно, не все ваши взаимодействия с пользователем требуют такого оптимистического подхода.
Важная роль в действии:
loadBuzz: function() {
this.dispatch(constants.LOAD_BUZZ);
BuzzwordClient.load(function(words) {
this.dispatch(constants.LOAD_BUZZ_SUCCESS, {words: words});
}.bind(this), function(error) {
this.dispatch(constants.LOAD_BUZZ_FAIL, {error: error});
}.bind(this));
},
BinaryMuse (создатель fluxxor) отправляет действие LOAD_BUZZ, а затем запускает асинхронный запрос с функциями успеха и сбоя, где отправляет успешное или неудачное действие.
Магазины могут прослушивать действие LOAD_BUZZ для оптимистического обновления или отображать значок загрузки svg, а затем прослушивать успешные и ошибочные действия для окончательного уведомления об успехе или ошибке (плюс сохранить BUZZWORD в магазине).
onLoadBuzz: function() {
this.loading = true;
this.emit("change");
},
onLoadBuzzSuccess: function(payload) {
this.loading = false;
this.error = null;
this.words = payload.words.reduce(function(acc, word) {
var clientId = _.uniqueId();
acc[clientId] = {id: clientId, word: word, status: "OK"};
return acc;
}, {});
this.emit("change");
},
Я думаю, что Sophie, что запросы ajax не должны блокировать действие от отправки, потому что это будет больше похоже на синхронный запрос на сервер, и на него повлияет отзывчивость страницы.