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


Диспетчер (Dispatcher)

Диспетчер используется для направления нагрузки к зарегистрированным ф-ям обратного вызова(колбекам). Существует два отличия от паттерна издатель|подписчик:

- колбеки не подписаны к конкретным событиям. Каждая нагрузка передается к каждому зарегистрированному колбеку.
- колбеки могут замораживаться целиком или частями до тех пор пока другие колбеки не будут выполнены.

API


register(function callback): string Регистрирует колбек, который вызвается при каждой передаваемой нагрузке. Возвращает маркер, который может быть использован с waitFor().

unregister(string id): void Удаляет колбек основываясь на его маркере.

waitFor(array ids): void Ждет колбеки определенные для вызовов, прежде чем продолжить выполенине текущего колбека. Этот метод должен использоваться колбеком в ответ на передаваемую нагрузку.

dispatch(object payload): void Передает нагрузку ко всем зарегистрированным колбекам.

isDispatching(): boolean Если этот Диспетчер выполняется.


Пример


Для примера рассмотрим эту гипотетически "полётую" авиа-форму, в которой выбирается столица, когда выбрана страна.

var flightDispatcher = new Dispatcher();

// Отслеживаем какая страна выбрана
var CountryStore = {country: null};

// Отслеживаем какой город выбран
var CityStore = {city: null};

// Отслеживаем базовую цену полёта в выбранный город
var FlightPriceStore = {price: null};


Когда пользователь меняет выбранный город, мы передаем нагрузку:
flightDispatcher.dispatch({ 
actionType: 'city-update',
selectedCity: 'paris'
});


Эта нагрузка переваривается CityStore:
flightDispatcher.register(function(payload) { 
if (payload.actionType === 'city-update') {
CityStore.city = payload.selectedCity;
}
});


Когда пользователь выбрал страну мы передаем нагрузку:
flightDispatcher.dispatch({ 
actionType: 'country-update',
selectedCountry: 'australia'
});


Эта нагрузка переваривается обоими хранилищами:
CountryStore.dispatchToken = flightDispatcher.register(function(payload) {
if (payload.actionType === 'country-update') {
CountryStore.country = payload.selectedCountry;
}
});


Когда колбек обновится, регистрируется CountryStore. Мы сохраняем ссылку на возвращенный маркер. Используя этот маркер с waitFor(), мы можем гарантировать, что CountryStore обновится прежде чем колбек, который обновит CityStore необходимыми ему данными.
CityStore.dispatchToken = flightDispatcher.register(function(payload) { 
if (payload.actionType === 'country-update') {
//`CountryStore.country` возможно не будет обновлен.
flightDispatcher.waitFor([CountryStore.dispatchToken]);
//`CountryStore.country` теперь гарантированно будет обновлен.

//Выбираем столицу новой страны
CityStore.city = getDefaultCityForCountry(CountryStore.country);
}
});


Исопльзование waitFor() может быть "по цепочке", например:
FlightPriceStore.dispatchToken = 
flightDispatcher.register(function(payload) {
switch (payload.actionType) {
case 'country-update':
case 'city-update':
flightDispatcher.waitFor([CityStore.dispatchToken]);
FlightPriceStore.price = getFlightPriceStore(CountryStore.country, CityStore.city);
break;
}
});

Нагрузка country-update будет гарантированно вызывать зарегистрированные колбеки хранилиц в следующем порядке: CountryStore, CityStore, и затем FlightPriceStore.