Aktualizace výpisu na stránce pomocí Rx
|
Včera jsem začal implementovat aktualizaci času na výpisu typu friend feed. Dnes se podíváme na to, jak si zjednodušit práci s asynchronním voláním na server. Samozřejmě opět s využitím jQuery a Reactive Extensions.
Asynchronní volání
Asynchronní volání je z pohledu šetření zdroji výhodné, ovšem z hlediska psaní a údržby kódu už to taková sláva není. Proto nám na pomoc přicházejí Rx, které asynchronní operace převádějí na neblokující lineární kód.
Pojďme hned k dnešní ukázce, která bude o dost jednodušší než včera. Ale použitá technika a principy zůstávají stejné:
Rx.Observable.
Interval(60000).
Select(getFeedUpdates).
Switch().
SelectMany(function(result) {
return $(result).find('.hentry').toArray().reverse().toObservable();
}).
Subscribe(function(entry) {
var feed = $('.hfeed')
feed.prepend(entry);
$('.hentry:last', feed).remove();
});
Opět vytvářím Observable
objekt, který něco vystřelí jednou za minutu. Tajemství funkce getFeedUpdates
si nechám na později. A rovnou se vrhnu na zpracování dorazivších výsledků. Výsledkem mého asynchronního volání je kus HTML kódu s vygenerovaným feedem s novými příspěvky. Z tohohle kusu HTML si vyberu jen elementy s třídou hentry
. Ty jsou seřazeny podle data sestupně, ale já chci feed aktualizovat postupně od nejstarších příspěvků k nejnovějším, takže je otočím funkcí reverse
a pošlu je do světa jako Observable
objekty.
Nakonec se přihlásím k odběru těchto jednotlivých příspěvků pomocí operátoru Subscribe
. Když mi nějaký příspěvek přilítne, tak ho vezmu a dám ho na začátek feedu a potom odeberu poslední záznam, aby se nám feed na stránce nenatahoval. Takže jsme elegantně zvládli příjem nových příspěvků. A jak je vlastně načítáme?
function getLastActivityDate() {
return $('.hfeed>.hentry .updated .value-title').first().attr('title');
}
function getFeedUpdates() {
var subject = new Rx.AsyncSubject();
var data = { lastActivity: getLastActivityDate() };
jQuery.post("url", data, function(result, status) {
if (status == "success") {
subject.OnNext(result);
subject.OnCompleted();
}
else {
subject.OnError(result);
}
});
return subject.AsObservable();
}
Funkce getLastActivityDate
načte datum posledního zobrazeného příspěvku, které slouží k načtení novějších příspěvků ze serveru. Opět k tomu využívám mikroformátu hAtom
a jeho konkrétní implementaci v mé stránce.
Podívejme se ale raději na další funkci. To je výše zmiňovaná getFeedUpdates
, která nám transformuje asynchronní volání na objekt Observable
a to pomocí třídy AsyncSubject
. Povšimněte si, že v callbacku asynchronního volání vrátím přes closure data do subjektu, který už je tou dobou pozorován první ukázkou kódu.
Když přijde odpověď od serveru, je zavolána metoda OnNext
, která vyhodí přijatá data dál ke zpracování. A vzhledem k tomu, že na jeden dotaz asi více odpovědí nepřijde, tak taky ukončíme vysílání výsledků pomocí metody OnComplete
. Kdyby náhodou něco na serveru selhalo, máme tu ještě metodu OnError
, jejíž zpracování nikde neřeším. :)
Ale vězte, že chyby můžete zpracovávat stejně snadno jako normální data.
No a to je pro dnešek vše. Tuhle ukázku si bohužel vyzkoušet nemůžete, protože k ní už je zapotřebí i serverová část a ta ještě není venku. Příště se možná podíváme, jak pomocí Rx snadno a rychle vytvořit poměrně sofistikovaný našeptávač.
Okomentováno