Статьи / JavaScript / Reactjs (документация, руководство, примеры, flux) / Flux


Flux: Действия и Диспетчер

Где Диспетчер подходит для потока Поток данных


Диспетчер - синглтон, и работает как центральный концентратор потока данных в потоке приложения. По существу, это реестр обратных вызовов, и может вызывать эти обратные вызовы в заданном порядке. Каждое хранилище регистрирует обратный вызов в диспетчере. Когда новые данные поступают в диспетчер, то используются эти обратные вызовы, чтобы распространить эти данные на все хранилища. Процесс вызова функции обратного вызова инициируется посредством метода dispatch(), который принимает объект полезных данных (payload) в качестве единственного аргумента.

Действия и ActionCreators


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

Различия между действиями выявляются атрибутом типа. Когда все хранилища получают действия, они, как правило, используют этот атрибут, чтобы определить как они должны реагировать на него. В потоке приложения, и хранилища и виды контролируют себя; они не действуют как внешние объекты. Действия текут в хранилища через обратные вызовы, которые они определили и зарегистрировали, а не через сеттер методы.

Позволение хранилища обновлять себя, устраняет многие запутанности, которые обычно встречаются в MVC приложений, где каскадные обновления между моделями могут привести к неустойчивому состоянию и сделать точное тестирование очень сложным. Объекты в пределах потока обладают высокой расцепляемостью, и придерживаются очень сильно Закона Деметры, что каждый объект в системе должен знать как можно меньше о других объектах в системе. Это приводит к программному обеспечению, которое легче поддерживать, гибкому, проверяемому, и упрощает понимание для новых членов инженерной команды.


Зачем нам нужен Диспетчер


По мере роста приложение, зависимости между различными хранилищами растут. Хранилище А неизбежно будет нужндаться в хранилище B, чтобы обновить себя, прежде чем, хранилище B узнает, как обновить себя. Нам нужно чтобы диспетчер имел возможность ссылаться на функцию обратного вызова для хранилища B, и завершил эту функцию обратного вызова, прежде чем двигаться вперед с хранилищем А. Чтобы декларативно утвердить эту зависимость, хранилище должно быть в состоянии сказать диспетчеру, "Мне нужно ждать чтобы хранилище B завершило обработку этого действия". Диспетчер предоставляет эту функциональность с помощью метода waitFor().

Метод dispatch() обеспечивает простое, синхронное повторение обратного вызова, вызов по очереди. Когда waitFor() встречается в одном из обратных вызовов, выполнение этого обратного вызова останавливается и waitFor() дает нам новый цикл итерации над зависимостями. После того, как весь набор зависимостей будет выполнен, продолжнит выполняться оригинальный обратный вызов.

Кроме того, метод waitFor() может быть использован по-разному для различных действий, в рамках обратного вызова того же хранилища. В одном случае, хранилищу A, возможно, потребуется подождать Хранилище B. Но в другом случае, ему, возможно, потребуется подождать Хранилище С. Использование waitFor() в блоке кода, который является специфичным для действия позволяет нам иметь точный контроль из этими зависимостями.

Однако, если у нас есть циклические зависимости, то возникают проблемы. То есть, если хранилище A должно ждать хранилище B, и хранилище B должно ждать хранилище А, то мы могли бы скатиться в бесконечный цикл. Диспетчер способен в Flux репо защитить от этого, бросая информативный ошибку, чтобы предупредить разработчиков, у которых произошла эта проблема. Разработчик может создать третье хранилище и решить циклическую зависимость.