Я создаю приложениеact.js с потоковой архитектурой и пытаюсь выяснить, где и когда должен быть сделан запрос данных с сервера. Есть ли какой-нибудь пример для этого. (Не TODO приложение!)
источник
Я создаю приложениеact.js с потоковой архитектурой и пытаюсь выяснить, где и когда должен быть сделан запрос данных с сервера. Есть ли какой-нибудь пример для этого. (Не TODO приложение!)
Я большой сторонник размещения асинхронных операций записи в создателях действий и асинхронных операций чтения в хранилище. Цель состоит в том, чтобы сохранить код модификации состояния хранилища в полностью синхронных обработчиках действий; это делает их простыми для рассуждения и простыми для модульного тестирования. Чтобы предотвратить несколько одновременных запросов к одной и той же конечной точке (например, двойное чтение), я перенесу фактическую обработку запроса в отдельный модуль, который использует обещания для предотвращения множественных запросов; например:
class MyResourceDAO {
get(id) {
if (!this.promises[id]) {
this.promises[id] = new Promise((resolve, reject) => {
// ajax handling here...
});
}
return this.promises[id];
}
}
В то время как читает в магазине включают асинхронные функции, есть важное предостережение , что в магазинах не обновлять себя в обработчиках асинхронных, но вместо того, чтобы стрелять действие и только огонь действие , когда приходит ответ. Обработчики для этого действия заканчивают тем, что делали фактическое изменение состояния.
Например, компонент может сделать:
getInitialState() {
return { data: myStore.getSomeData(this.props.id) };
}
В магазине был бы реализован метод, возможно, что-то вроде этого:
class Store {
getSomeData(id) {
if (!this.cache[id]) {
MyResurceDAO.get(id).then(this.updateFromServer);
this.cache[id] = LOADING_TOKEN;
// LOADING_TOKEN is a unique value of some kind
// that the component can use to know that the
// value is not yet available.
}
return this.cache[id];
}
updateFromServer(response) {
fluxDispatcher.dispatch({
type: "DATA_FROM_SERVER",
payload: {id: response.id, data: response}
});
}
// this handles the "DATA_FROM_SERVER" action
handleDataFromServer(action) {
this.cache[action.payload.id] = action.payload.data;
this.emit("change"); // or whatever you do to re-render your app
}
}
flux
, вводится в магазины после строительства, поэтому нет хорошего способа получить действия в методе инициализации. Вы можете найти несколько хороших идей из изоморфных потоков Yahoo; это то, что Fluxxor v2 должен поддерживать лучше. Не стесняйтесь, напишите мне, если вы хотите поговорить об этом больше.data: result
должно бытьdata : data
, верно? нет нетresult
. возможно, лучше переименовать параметр данных в полезную нагрузку или что-то в этом роде.Fluxxor имеет пример асинхронного взаимодействия с API.
Это сообщение в блоге рассказывает об этом и было размещено в блоге React.
Я считаю, что это очень важный и сложный вопрос, на который пока нет четкого ответа, поскольку синхронизация программного обеспечения внешнего интерфейса с бэкэндом все еще является проблемой.
Должны ли запросы API выполняться в компонентах JSX? Магазины? Другое место?
Выполнение запросов в магазинах означает, что если 2 магазинам нужны одни и те же данные для данного действия, они выдадут 2 похожих запроса (если вы не введете зависимости между магазинами, что мне действительно не нравится )
В моем случае мне показалось очень удобным помещать обещания Q в качестве полезных данных действий, потому что:
Аякс это ЗЛО
Я думаю, что Ajax будет все меньше и меньше использоваться в ближайшем будущем, потому что об этом очень трудно рассуждать. Правильный путь? Рассматривая устройства как часть распределенной системы, я не знаю, где я впервые наткнулся на эту идею (возможно, в этом вдохновляющем видео Криса Грейнджера ).
Подумай об этом. Теперь для масштабируемости мы используем распределенные системы с возможной согласованностью в качестве механизмов хранения (потому что мы не можем превзойти теорему CAP и часто хотим быть доступными). Эти системы не синхронизируются посредством опроса друг друга (за исключением, может быть, операций согласования?), А скорее используют структуры, такие как CRDT и журналы событий, чтобы в конечном итоге все члены распределенной системы были согласованными (участники будут сходиться к одним и тем же данным, если будет достаточно времени) ,
Теперь подумайте, что такое мобильное устройство или браузер. Это просто член распределенной системы, который может страдать из-за задержки в сети и разбиения сети. (т.е. вы используете свой смартфон в метро)
Если мы сможем создать сетевые разделы и базы данных, допускающие скорость сети (я имею в виду, что мы все еще можем выполнять операции записи в изолированный узел), мы, вероятно, сможем создать программное обеспечение внешнего интерфейса (мобильное или настольное), основанное на этих концепциях, которое будет работать в автономном режиме, поддерживаемом из коробки без функции приложения недоступен.
Я думаю, что мы должны по-настоящему вдохновиться тем, как базы данных работают над архитектурой наших веб-приложений. Стоит заметить, что эти приложения не выполняют ajax-запросы POST и PUT и GET для отправки данных друг другу, а используют журналы событий и CRDT для обеспечения возможной согласованности.
Так почему бы не сделать это на внешнем интерфейсе? Обратите внимание, что бэкэнд уже движется в этом направлении, и такие инструменты, как Kafka, широко используются крупными игроками. Это как-то связано с Event Sourcing / CQRS / DDD тоже.
Посмотрите эти удивительные статьи от авторов Кафки, чтобы убедить себя:
Возможно, мы можем начать с отправки команд на сервер и получения потока серверных событий (например, через веб-сокеты) вместо запуска Ajax-запросов.
Мне никогда не было очень удобно с запросами Ajax. Как мы, разработчики React, склонны быть функциональными программистами. Я думаю, что трудно рассуждать о локальных данных, которые должны быть вашим «источником правды» вашего веб-приложения, в то время как реальный источник правды фактически находится в базе данных сервера, а ваш «локальный» источник правды, возможно, уже устарел. когда вы его получите, и никогда не приблизитесь к реальному источнику значения истины, если не нажмете какую-нибудь хромую кнопку «Обновить» ... Это инженерия?
Однако все же немного сложно спроектировать такую вещь по некоторым очевидным причинам:
источник
this.dispatch("LOAD_DATA", {dataPromise: yourPromiseHere});
Вы можете запросить данные либо в создателях действий, либо в магазинах. Важно не обрабатывать ответ напрямую, а создать действие в обратном вызове ошибки / успеха. Обработка ответа непосредственно в магазине приводит к более хрупкому дизайну.
источник
Я использовал пример Binary Muse из примера Fluxor ajax . Вот мой очень простой пример, использующий тот же подход.
У меня есть простой магазин продуктов, некоторые действия с продуктом и компонент просмотра контроллера, который имеет подкомпоненты, которые все реагируют на изменения, сделанные в магазине продуктов . Например продукт слайдер , продукт-лист и продукт-поиск компоненты.
Поддельный клиент продукта
Вот фальшивый клиент, который вы могли бы заменить для вызова конечной точки, возвращающей продукты.
Продуктовый магазин
Вот Магазин Продуктов, очевидно, это очень минимальный магазин.
Теперь действия продукта, которые делают запрос AJAX и в случае успеха запускают действие LOAD_PRODUCTS_SUCCESS, возвращая продукты в магазин.
Действия продукта
Поэтому вызов
this.getFlux().actions.productActions.loadProducts()
любого компонента, прослушивающего этот магазин, загрузит продукты.Вы можете представить себе разные действия, которые будут реагировать на взаимодействие с пользователем, например, и
addProduct(id)
removeProduct(id)
т. Д. По той же схеме.Надеюсь, что этот пример немного поможет, так как я нашел это немного сложным для реализации, но, безусловно, помог сохранить мои магазины на 100% синхронными.
источник
Я ответил на связанный с этим вопрос здесь: Как обрабатывать вложенные вызовы API в потоке
Билл Фишер, создатель Flux https://stackoverflow.com/a/26581808/4258088
То, что вы в основном должны делать, это указывать с помощью действий, какие данные вам нужны. Если магазин получает информацию о действии, он должен решить, нужно ли ему извлечь какие-либо данные.
Хранилище должно отвечать за накопление / выборку всех необходимых данных. Важно отметить, что после того, как хранилище запросило данные и получило ответ, оно должно инициировать само действие с извлеченными данными, в отличие от хранилища, обрабатывающего / сохраняющего ответ напрямую.
А магазины могут выглядеть примерно так:
источник
Вот мой взгляд на это: http://www.thedreaming.org/2015/03/14/react-ajax/
Надеюсь, это поможет. :)
источник