Диспетчер (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.