Каковы наилучшие методы при работе с данными из нескольких источников в Flutter / Bloc?

#flutter #dart #bloc

#flutter #dart #блок

Вопрос:

В руководстве Bloc описан пример простого приложения Todos. Это работает как пример, но я застреваю, пытаясь превратить его в более реалистичное приложение. Очевидно, что более реалистичное приложение Todos должно продолжать работать, когда пользователь временно теряет сетевое соединение, а также время от времени проверять сервер на наличие обновлений, которые пользователь мог добавить с другого устройства.

Итак, в качестве базовой модели данных у меня есть:

  • dataFromServer , который обновляется каждые пять минут, и
  • localData , который описывает, какие изменения были внесены локально, но еще не синхронизированы с сервером.

Моя текущая идея состоит в том, чтобы иметь три вида событий:

  • on<GetTodosFromServer>() который запускается каждые несколько минут для проверки обновлений на сервере и изменяет только dataFromServer ,
  • on<TodoAdded>() (и его друзья TodoDeleted , TodoChecked , и так далее), которые срабатывают, когда пользователь изменяет данные, и только изменяют localData , и
  • on<SyncTodoToServer>() который запускается всякий раз, когда пользователь изменяет список задач или когда сетевое подключение восстанавливается, и пытается отправить изменения на сервер, извлекает новое значение с сервера, а затем устанавливает новое dataFromServer и localData .

Очевидно, что между этими тремя методами существует большое взаимодействие. Когда новое задание добавляется после запуска синхронизации с сервером, но до завершения синхронизации, оно должно оставаться в локальном объекте изменений. Когда GetTodosFromServer и SyncTodoToServer возвращают данные сервера, им нужно выяснить, у кого есть последние данные, и сохранить их. И так далее.

Исходя из фона Redux, я привык иметь два редуктора (один для локальных данных, один для данных сервера), которые будут реагировать только на простые действия. Например. действие { "type": "TodoSuccessfullySyncedToServer", uploadedData: [...], serverResponse: [...] } было бы просто проанализировать как для, так localData и dataFromServer для редуктора. Редуктор не содержит никакой бизнес-логики, он получает действия одно за другим, и все, о чем вам нужно подумать внутри редуктора, — это состояние перед действием, само действие и состояние после действия. Все, на что вы полагаетесь для обработки действия, будет в самом действии, а не в контексте. Таким образом, разные фрагменты кода, которые генерируют эти действия, могут просто запускать эти действия, не задумываясь, зная, что редуктор обработает их правильно.

С другой стороны, Bloc, похоже, смешивает бизнес-логику и обновление состояния. Вызовы API выполняются в обработчиках событий, которые выдают значение, возможно, много секунд спустя. Поэтому каждый раз, когда вы возвращаетесь из асинхронного вызова в обработчике событий, вам нужно подумать о том, как могло измениться состояние во время выполнения этого вызова, и о последствиях, которые это имеет для того, что вы делаете в данный момент. Кроме того, объект в состоянии может обновляться различными событиями, которые должны координировать между собой, как избежать конфликтов при этом.

Существует ли наилучшая практика в отношении того, как избежать связанных с этим сложностей? Лучше ли разбивать большие события на события «StartSyncToServer» и «SuccessfullySyncedToServer», где второе ведет себя во многом как редуктор Redux? Я не вижу ничего из этого в примерах, так есть ли другой способ избежать этой сложности в блоке? Или Блок полностью не ориентирован на эти вещи?

Я не ищу здесь личных мнений, только если я что-то пропустил в руководстве Блока (или другом авторитетном источнике) о том, как это должно было работать.