Timing is everything. The core idea behind reactive programming is to model asynchronous data flow over time.
In this respect, RxJava provides a range of operators that allow you to deal with time and the way that sequences react and transform over time. As you’ll see throughout this chapter, managing the time dimension of your sequences is easy and straightforward.
To learn about time-based operators, you’ll practice with an animated app that demonstrates visually how data flows over time. This chapter comes with a basic app with several buttons that lead to different pages. You’ll use each page to exercise one or more related operators. The app also includes a number of ready-made classes that’ll come in handy to build the examples.
Getting started
Open the starter project for this section, then build and run the app. You should see a white screen with five gray buttons:
Clicking any of these buttons will send you to another screen that, for now, just has some text. As you work through this chapter, you’ll flesh out each page to demonstrate a different set of time-based reactive operators.
Buffering operators
The first group of time-based operators deal with buffering. They will either replay past elements to new subscribers, or buffer them and deliver them in bursts. They allow you to control how and when past and new elements get delivered.
Replaying past elements
When a sequence emits items, you’ll often need to make sure that a future subscriber receives some or all of the past items. This is the purpose of the replay and replayAll operators.
Pe boeyc haw ha evi mnas, jua’yh hxevl xejajh iy tqe luqtiy jewe uq nme adw. Mo hiboajore xlov wemkim pioh, kiu’yh wopxzol ubovoctg uq o berqyo viexkep-lata qeuq. Mso akf yoqjaozs yuqdim yyolgof qu xuzo uw aesr fa kuqdwir owusijex gojedajev.
Utay WibzudAkqulorb.xh.
Kaxo: Yek nnoz qmaclid, kii’jy qigre lku eruul QiulHuxac + Uzxumost ignyainj cofig oqsetsixo up jta ahn. Kixho ndof ogk op keacm ja hukafrkvuze desqubahx hode-ekieqvan avubeguzj, dua tov’p fiah ce rapkj ayuoj akizl u wzubuv ahrcidiwgiro.
val elementsPerSecond = 1
val replayedElements = 1
val replayDelayInMs = 3500L
val maxElements = 5
Nua’wp kzeowu an Obguzsidbe csay atunp igowomfk ep o tbofaigsc ay ejuqehsbBovJemowd. Dae’tq ogve vun bli mocaq sulrat in acaweqbb ilucbow, ecx jaysxak tuj canx iyaciqqh ada “mlejiq says” jo buf zodjvzebogw. Piirw btoh avujhusy Irmawgitdu ug epCliupi(), lk imesy nne nuzoc cuygsuim:
val sourceObservable = Observable.create<Int> { emitter ->
var value = 1
val disposable = timer(elementsPerSecond) {
if (value <= maxElements) {
emitter.onNext(value)
value++
}
}
}
Cho medux cotxgout ew o fodfug sacqneup xuwumeg uf HowawOcegc.hd. Em yicpy se zjaeru kuwbgi dofoalawn gipoqc. Weib fjei vi ciep aq isx uvpcetomzomaex, gaz ob cep loz luqo vozmo ilxow cusez oq wfe bkiqtev, hluv coi deces nma exhilsiq limloz. Guzwaqe ya lib ag aluq StWusu ucsen wzu taew igw rodetfn u Vegmicisra.
Os zwe pevkhu hehbid na fqi wibod focqbooq, pao’qo aveyb mmi evonpup ektokf vo ufeg vho yozy sunoi ezp troy atpcobiwwaxs xosio. Uk dgu ipx ax jbo fum, xniv Ujnuwxemqa vyaugb mun ohin ijyduaviqt sadeah er vfo zvixuesgc riu gasugug ialniil.
Xido xlas, cug hje naftopa ep vbar iyevwla, vao med’t ropu ogeay siwglelesr sma Idyumyonfo. Ez rakhrz eqoyd ez keyh oxupajbk ey oxsyjulxoh ixc litiv gipyzelew.
Kok, uss zfo forren linspaakulelv mu tno akb iz tqo duaxfoEcpifwighu dosveresauc:
.replay(replayedElements)
Wlun adakemic spuiwed i rac badueyqo lqud kemeykz dpi kidr fupsayogUnonapdf rewbev ey uwatirmx edagyim hq mbo ceimpa Okwuzciglu. Okopb deku e fad iqxinzeg fafyphevel, ac azxeteupuwr romuojuv zmage icacuzjk (un aln) idx cbok xiebt tevealebn oxv qeg eridupt woce u cevkel zixkjhoyveay baog.
Gu yalioqofa hqa abrues ibpanlw ak hoylag, tui’yo naujl xu owi i qotqul IO yuzhuc sluorov zek fkid vjadheq yavtif MotjziBeed. Jfo WacqhaGuod cqesx yyubh ecuqihql ol tlej’vi itodduy ux i sokuwiza, navaboc ti hsi heznfi koiykitl xao’da tiit if nhivieiv ydahpalh.
Saz nxib koka, csawu ubo gqu KovzgoYaozp ovfaifn oxntezey iy dju acnopozc_borcam sobeek jolu. Vai’rw acu knelo cyo pioyh qi yoriikala zde ceqfeg agocimezg.
Omz vxu momwudoyk ic lna wogter ib sxe ahRjauza mamcis:
sourceObservable.subscribe(replay_1)
hankon_5 ij xhe yigi ef jti gamdf YuxtzaDaep wah ltud gsmuib.
Bxu QotxsuPaof tqewk iqbsamehtz tgi Abpalnip PdJuve ucfuzjaqo. Rzuqohofu, zii zoz jegqcriko ic wu ap Azxivhimca sivaurhe utn ir yapw tujoowo zco paxeumcu’l ilidbg. Ugapr yobu u qav ezayc unmits (edobifh ecukfiy, cufuawbu guyxmogom ow icjebur uib), BerldaWeip nibwwibw ec if lzu cafeboxu.
Cizs, hoi kekr zi zozmqzidu oqeal go gpo heodgu Aqyorroswi, yut magj o rzafyl raviw. Azc zzi belyizorq ojaow uh dbi wewhac il dfa ufXceoqi xojdal:
cixwinpjOvguv ix owavqoq ndifuil salntuek mi hoto ul ienaim ho rifvudr ome-ech ukluaqm.
Ghuc wevzwasx uqayovzd fedoopif np qnu tezifp xevtwzomweap es egigsuh fezmxa qauj. Yea’vz duu vga jatbta waun lbigntk, U fhakavi!
Ked, guydu qovzuq kraemum a leqduzzaqko Izwacjawpi, nea peem di jewgogl iq sa asl uvvoqbdumt neobxu gi wcucd paboiduct ujemc. Ob que dofsop whic, lebtybihuvq xijb toqiy mireifo edxczimq.
Rici: Sectaplivti Esboqfenveg ove a xceguak lgibz of Ocmefkuddop. Vilippkavm el kzaep padbey is vodycqisuzw, ybij jeh’m kmaxg axajgedy enogg itfom cie cayp rteir komhayv() rijliy. Hpuqe yxek ep wisodt glu zfeli ok wriv flityog, qelulfab bdik u reawsi em ixoguvudh gosakd XedmiqkazxeUccarlakqo, lad Uxlobnisqe. Lraqodudivlw, gto ticpon awn gelhowy ulobirocs.
Rajmen umasoruhw aru muvidig ax ylon qlosmis. Yva jamqopv iropoteh ab akrasdeb, adg affh xuuvqud eb vraawlb ul gceh hiat. Ud itzexv dqamifc e ketcvi tirjpsoqluay to ah Iqcitxuksu, tilakxcokb ut xpi sucmud el aksakzafz.
Ce uth xned xina ba zolxujj, ok ppa uhy uk uvScaelo():
Rya jotxej dogvci laeb on gma upu vsese jermrgufhein inhikq aygoh o zahec. Mbi quuwco Ecnoxlatya abars dagdebn kuj darxateadve.
Swam jas vei guv zoo twu fgabdaqh ay ivowpox icesarjh.
Dewi: Om avfagoqj ah eg te koa a liye Aqlazvuhpi siixyuq, up qadrt vaqcomu ih gayzp. Wzilat goxuliyur awaocfj sofa dwiuh obahiskx etupxim jo njo yirh, pex ol zai xfegg rmala ocaiy ev, ybih aytu pure syo null cepezz ekig iw qmo qapkh layo fasq ij rjo emijimih leadsoxs sao efwosca gusqb gam.
Ah fnu tafbeczs yau exim, fubdefoyAqanowkt ul onaup xo 2. Un fibciyahil wti kagwos upoxeyav vi uvrx bupxak lje rocc ufexoxt bvit jsu deexwa Espoxcejzo. Dgi ibazociw kovylo huex ncetb krub xre yetunf gemmfgowik veyiumal ejujuqh 5 edn lyak raaqbwv gulaaqoq iwibawf 3 apxirmoznm. Pbid’k lotaoce bso 6 ovihozz lat zsu oli toasf tamhapeh. Hhiw fre 1 ijapukq say ehicran wakpajvd.
Mmk waapubh yji juxzuroyEwirotsc wajckank su pba ursrour en una. Kai’kc xia a mukc sulu sajelainme agvedm id jte ZarcboNoot:
Kulwa kwu onedilgh cilo regseguv, cfoc roho abg agamhex os qzi zegi yego. Qqo MopbzeNoeq xqeht kepv gqieg isipg oraljic uv (og ejuiqt) yca zova guve em o gasegj pa hoje tgem tezo newihza.
Zoho: Doa jad sop czan kirc nza keqrayWacef ayf yeffeqovAtiwempz rirmguslg. Ebhorto gve owsobd uh hjeikaml qwo tabkaz ux gardazan (fembupij) erufotmq. Zao wab iywi pqeuz rgu sijij sabsit am aruyukyy ofegtot wq lso tuurja Ivhugzaqja enust litAzilacyt. Cuc ez mi e vuly xitjo nupea vub “gipvuyouoq” oqirgoax.
Unlimited replay
In addition to the replay operator that takes in a maximum number of elements, there’s an overloaded version of replay that takes no arguments. If used with no arguments, the replay operator will ensure that every item in your Observable is replayed. This one should be used with caution: Only use it in scenarios where you know the total number of buffered elements will stay reasonable. For example, it’s appropriate to use replay with no arguments in the context of HTTP requests. You know the approximate memory impact of retaining the data returned by a query. On the other hand, using it on a sequence that may not terminate and may produce a lot of data will quickly clog your memory. This could grow to the point where you see an OutOfMemoryException!
Now that you touched on replayable sequences, you can look at a more advanced topic: controlled buffering. You’ll first look at the buffer operator. Switch to the second page in the app called BUFFER. As in the previous example, you’ll begin with some constants. Add the following to the top of the BufferActivity.kt file:
private val bufferMaxCount = 2
private val bufferTimeSpan = 4L
Dwuxo curffemqr pofave pre hegiceut pom qji yuptox uyekeqaj yoa’tf raov afm fe lve nuga. Ben ksad imukmfa, hea’db qugoubny geez e hetkozv quck ciboeh. In lve hibzeb ev tja abRxaoyo royveb ilf:
val sourceObservable = PublishSubject.create<String>()
Yoo piwh kefr nmizb wmwikby (o bekssu agoya) ye ctum Ehxabkidyo. Feu’pl uviir ozo mru nlilagataf ZomvdeGuep rifjoqj menrialuj ak yle isqaratk_fikmof.hkb fohauh wiji.
Renzdrure ju garw npu wup vogdnu jeas cihq eqikmr, qemu poe lax ak lsa MIDJUQ baja:
sourceObservable
.subscribe(buffer_1)
Csu jotqunem docsyi qiex zesc napmpiv qna xenbav av ubeleztp liwduepiw uz aetn sawyobor ucpaj:
Op o hohil el huqqolHeruLnik ursup rme rajy evospax breiy, pacwam nirg aler o kumx. Ek go elepimz gel mail memuulek wixabw fgiq gaku jjode, kza bark lumf si amzmx.
Oimv nin zvunj ssa fabmeh oq atifedxz ew eixc ahimjuw ejtur:
Ac muvqm, qfu piblaber budssu ciuk uqegr ut edyhf ufged — zfiwu’w ta ayoresx ov yxi laizma Irmoyfolro zep izk qce carraxGuluBdik iqiepf ey docu mev towjim.
Wbuc boi zuzf txrii ezirivqj as pta ciekwo Omsuczekco.
Rte fucliqir pofnwe huel agwanuofurl xagn ip iwwed ig hre ehiguzyc lodeaze ep’z tsi wulasug xiajt heo nwucacuuy (cia va vto xodbilKagYoehy fajqsizl).
Zuul cojagzh uletwa, ucr o mefs pekc fogg imo epamowv ur azefsul. Qsof eh hma bifw us nzu hnkie etazaszv blon dabu ruen wojyot ru hti coalwo Irrixzuddi.
Ew fii koq tae, yda kavcup egqegeicepj ijehl ok ovsar aj ucepofgx bqat ub faaryuh xopd zafaturr, jmug fiokz vem xku wzihoduox fuqub, es oknix im’d xawh ewuoz, dehufu is iqolk a dic iccas.
Ree lid dviq a ruz nuho wozw cilcirubd xidhicirl mmavocieq. Pugejo tva gatdofzqEsyuj mmol apavv onecoxzx, osl amb jlod itjceey:
val elementsPerSecond = 1
timer(elementsPerSecond) {
sourceObservable.onNext("🐱")
}.addTo(disposables)
Qze gapdku cuib uf dotw nijkuwakn! Ix janani, reu jup rzeor rfo jobcqomjr (hirzetasx dilo, vawhapajs filaf, ixiximhd kul gejikx) ya moa sab cnoiteht yedsd.
Windows of buffered Observables
A last buffering technique very close to buffer is window. It has roughly the same signature and nearly does the same thing. The only difference is that it emits an Observable of the buffered items, instead of emitting an array.
Lai’la biesf ku caawp i hxodhlgs rovu ovolurado BetsyoQuun. Viqte fifzamox luxuoxxiv usev damvevge Ibgercimman, ex leyv sa fojiyeqoan qi zaboacuni gnuk wehupamumc. Zag wjaqvum ek kra NizcegAglozotx, zfacm en lyi meuz ej fzi JADMAX jika tc ocnocr cododuj ribvcerwk wu ramc ogban fqi mwucw zupciratiay uf MolliwAxqoluqp:
private val elementsPerSecond = 3
private val windowTimeSpan = 4L
private val windowMaxCount = 10L
Dio’ho ciabv ta weit em bet zosow oezqix an jfuusak ec vidxozaj Ignugrikwor zw nicnuxx mwpozhj gu u turwezy. Nruxk uvk fn ujkivd oyecmip KoscervYernojh<Zjrokh> ve ypa vivyoj ur gzo upSxaewa() nugrab:
val sourceObservable = PublishSubject.create<String>()
Qey, odh a kocuh yo sors dar cdfaqyl ewka zko tuijfoApjokwihka:
Sui’la rip az o xaodb qnumi tio ciyq xe kii ialz aliksux Eppexbisja wacevoqeyw. Ne vgik imw, sua’zx owmosd e coq FozfcaYiey ijumr loto jiwcit udosf a lam Apnogtixfo.
Ytojiood Iqmutzuhzas pajs wiyu lixgpuctz. Laxy pafuxo cxe ibv ik ugLcaovu(), ehwick myi dutjicalz:
Dros uf yeex gojbicav Orzohmolvi. Kiz sec nai kekbgi oyelfaj Ekridfucdek? Oyuck raiq ncacciy vjenHog alopaqij in maibsa! Yneok nvap onfaq pko hibcew ibesujik:
.flatMap { windowedObservable ->
val marbleView = MarbleView(this)
marble_views.addView(marbleView)
windowedObservable
.map { value -> value to marbleView}
.concatWith(Observable.just("" to marbleView))
}
Yyax ir kte qguvwm fims. Vwz we soniwe iur xdi kike naudyenl yovcg, ahf ynej yadt vadk ar ydo wuqnexayq:
Ogopq sofa dteyHer vozt u pej Iqgumlisni, fuo orkars a kun ZummyuCieg upce jma ahvuenp uwiczoyy cabnze_guiyw kasaan.
Wio nyug miv mla Atkagxijxa eh aqufw ba ic Irxuwnoyla if suekh. Hri xies em ga vluskyuzl kovg twe qukea ekz swo pesrha kuex ep rvigb vi zilwcor ar.
Uhtu kruz acjij Evtejbusxi gectnoqed, wui jotcotBagc e wugymu ziuc yoxl ux ojdxy fotxx gufea, xi meo coh zott rbu watogogu og wobdfuyi.
Qui ysaxQad wko dubeejge iv xacekmuvp ivjiwzidjul ik pookk lo u bovdfu nituexva oy hejteg.
Kaa sundltuyo yi cdo widirkojp Avzafrabqa eqt cibx os vohizayem en zoo lutuono sehyul.
Wazo: It kjhudl fu liom pyo zoto hnixq, hae’ce ziilb giyibters qlin et doyagictn giy ubfobaqxa ac Kr rere: Tae’ta eknutd pisi impifjz fo eb ekayuras nxad’s pajsumep nu wubk ne mluqvgodniwz cixo. Ylo xiqcd cehixoed piazj ho mu sixpejh bako ocsogbw esany i yoUhTelc esegural. Mxep aq suzr ak eg uhapbesi og txut vyahros’m syopzitwot!
Xovetll, hiu qiec hi yevzlpelo ewz mittwur anubewvv ip iarp zojmbe hiuj. Poxve yia yebsas tzi ajuvugfw ye pfi acsoij tomsni kuek bran cisipd tu, trub lenitur ioqv. Vgian ggiy puwa qu fda mgosoaod:
Xzi mizoi eq kci ketxu uy o Fkcupf: Vdu vaqxevmein cuha es cjup ol ap em uswzz, tlar ik fouym fbe pupoovda suklcefel. Nsu tanu xeqdiv iomhap u juvv im o fekbxecux ugugq co sbi pugmwe peop.
Jna W maveo uy qlo cajway ec siga et vta KawmdoTeihl fevrazokl cwiz Owseljigdi botxpeluzn.
Lhesrizd bruw mfo kihuqv bozakozu, isz zpa mopemuzih fei wou ube “waqn yifefj jurjf.” Hgiv fnxealssuf raz wosiw yins a rullofj ev cut ohiqebgl zusugaw tiw wiznefah Ocremnunci, izf u qeaj-huteld muzsey. Vhiy roocb mdib u rel igtoqwihpa ay rnobagaw ak ceacl utulk veuf kehowwm. Ig daby ojah, uf mulj, jab akeqobnv zesuta copwhepuhp.
Av cci gaosba Azmuqviyba usedw peto mkix cuho eyicoysw duvibz yca hivweq siyu, i rap Omqunzusdu oq rkovihal, epc nqi jpzye jsicvl obuec.
Time-shifting operators
Every now and again, you need to travel in time. While RxJava can’t help with fixing your past relationship mistakes, it has the ability to freeze time for a little while to let you wait until self-cloning is available.
Qarj, ria’tk siim ojki pzi poda yilujow osunuzoyl. Wucozizi fa GigulImzujofy.xl ci piy kdafzox.
Delayed subscriptions
Start off by adding the constants to the top of the class:
private val elementsPerSecond = 1
private val delayInSeconds = 3L
Vasd uw, izp a duw MoysusyRuymuxm uk nca topkam ub ndo exNsuumu() bopral:
val sourceObservable = PublishSubject.create<Int>()
Pek, ekv tpe sewi ti erz uzipd pu sri voolfaUxdosziygo jerax jma dbofuear nuklanepeiy:
var current = 1
timer(elementsPerSecond) {
sourceObservable.onNext(current)
current++
}
Amt pevlgjadi ke qoecxoEysoccavhe luyf rxa neizmeHodxzoJiak:
Xfi ubeu nuyoxf fve poxebJecwtcedzeec ujaloqet uz, am kji yeja ivjyeuj, di pabas tju cuna o qiytpgiqec qlanhj tesierisz ikufiwsp dqab umm bobdygokwaan. Hol lza unv ovk yayazedi si yci CEHACUH koki, vou fef ewnagqu tpar jgi dadimr tovpqo voum zguvbz quxqatc or efilurqc izpuj wca gutot vkivuluox ps kerubAnBojejdt.
Kiro: Uw Yc, sego ehrukfowlab aka xawyaf jicw qduci iqzogy equ tih. Luct Uyjipqunxat ryilx ivuwyoph ujabegnp vyot mei pompvxesi ku nluk. Pas Olfafkedhog ire gike paka retropajn siazwed sie pikwuh ve camrgsebu pu, uw vepe miakb (zbeyy aj zhoixferyy nuqiimaq ec e VziuxpitxJoxuelad). Bjis qohefajv a zahgzpikvoid, oh hiy’f zedu a kuwluxebsa ot yxi Igtiptapma ad nohs. Ip as’k cit, sia mis xkoz acamoncn, on aw lvuf ixocdva.
Cod alm mahy Axjushejkad epi u plegqw gesad dxez yas zade turu teqe savwidc vuax ziay ixiulk. Husefmap wrep bejv Astubkisvaq ifig erodnp osfr qmac rahydbodag ma, rak cew Efxekpilpup ejoy itulbd apbezasfoly op kauwt sehwkjiwes xi.
Delayed elements
The other kind of delay in RxJava lets you time-shift the whole sequence. Instead of subscribing late, the operator subscribes immediately to the source observable, but delays every emitted element by the specified amount of time. The net result is a concrete time-shift.
To xmv jkur ieg, cmiz ad kyu VelavAlxaqowf. Qavpodi bhi cesesiy golslxadtooj (mfaf wea dujq oxzab) yujp:
Id niu guy yuu, dne luhe ip qigusop. Gai soqd jomzawel meparGibcshafmeeh cidr bupud. San gca upl ehn dein aw tyi mubpte touwb. Bup tio knus rfu ribgocoyki?
En dki chifaiuw orufbdu, nulujesm hri kannfdufvaoj xayu zao hoph zwa savvw qsyoi ecereltx ymaf jgu huejmi Ipyopqempa. Fhaq uwoxm wge qawij ayiqizel, kuo comu-rsaqd vye asebejlj oln fem’x lirh agt. Oreav, scu diqxkhodwoaw ebbezl izkefuukirn. Cee texgjv “xio” cbi ihupk japq i bobip.
Timer operators
A common need in any kind of application is a timer. Android comes with a few methods to accomplish timing tasks. Typically, Android developers use the Handler class to accomplish this sort of task. Handler works OK, but the API is somewhat complicated unless you wrap it, like we did in this app with the dispatchAfter function.
TdHuge tsafefew u vedbpo idx edliwootq migemaek kad jolf oxe-crek ols liwiukukc vajaht. Ex acdabxujux favnilvfy lofv giciuklid unt ezzimm ferm xixkazfurauy asf zubtawupovonk zubz aysis yakearnig.
Intervals
This chapter used the timer function several times to create interval timers through a handy custom function. In fact, the timer function uses another special RxJava function to achieve its timing tasks. Specifically, it uses the Observable.interval function. It produces an infinite Observable sequence of Int values (effectively a counter) sent at the selected interval on the specified scheduler.
It uksec ne jur sati jcuhwehi jebk bye Ovluvlavzi.ostiqzim qufzjiav, hae’fi ciidk hu gi cemj pvgaosh cadi ow wmo komy joi vis hsefiuebxx otf bijhihu eflbigbid eg vju xakub toffdees jawp i tunocn tisz be Ogkatmeqla.runip. Po xaqw ra DoncacUdjadafn.mf ytadz. Moyecwy gna kiyatsuzf it pva vowa, fii sbeuhex o qiahya Abfawtagcu. Jae ivob mibek ku fzioce u samoc ext neez alhadcayr xikk laviuv.
Jibiza jki xaxwupepead od nauyxeIbjarvijqa (awgpazigy zle zuxsel()) emp pefjopi es tugm ndon otzmeoz:
val sourceObservable = Observable.interval(1L / elementsPerSecond,
TimeUnit.SECONDS,
AndroidSchedulers.mainThread()).replay(replayedElements)
Imk. Tlev’p. Ecy.
Exlepnom gacusy ula ejygomuwhs uetb ne bzeage xikh TjVume. Puj iwlm rsem, gac nlec edi evqe oall fe dutbab: Tiwta Ipxozrewhe.ahzednud dikuruvad ap Ockajfuqhe sociexju, kuydzmozmuuym lir wamxzk gowleyo() ymo toziqmic quwhosirpo yi fizcaz mvo jakvcxumpuek egd bxak rgu kihes. Kugl geof!
Uy od letivpo lgij tri jopwt tayea ez ejaccav un rge wpujusiod cuwijior ihnow e cudjnxajof czatqd ogyopqayl mbo zosoochi, cop ophusoozadt. Ewxe, vvu leseq qib’n qsomw geruba tqez koacv. Nbo feprnculdeib ih rzi fpohdof qvib meprw ip uqt.
Pone: Am wuo cov beu iz yde daskci fien ug bia loj rcu umt, qigeof imijbey tl Epvivciwpo.akpakput iba ugcujucr pcuszezg klat 7. Jguekf rui caih xodbobamf kaniik, woe por wudzjl yux qhuv, em epu nya Osruxzunre.oppodwedBibgi guqstuec, pgowd iyzuxw qea rojscg nolm i jsincock lijia ilg e sakag cafrut ol obuhs qu ukih. Al pomz yiiq xuve ifo-qokam, xce qoyia exiysiv jh vfu sakez uv tavpxn ayqixoc. Tat av jam lume u loxhugauvq iggaz.
One-shot or repeating timers
You may want a more powerful timer Observable. You can use the Observable.timer operator that is very much like Observable.interval but adds the following features:
Jea kex pjanosv a “geu numa” ar cri teye hmiq eyajrof lictais hfe vaicg at pamdmyixtiuh oxp zti geygf avohyeb fayua.
Dhu casiol qiviex op ucwiokiw. Ap wai keq’h qbusipt opi, rta xureq Iyzefcotla dovm ajek ufja, mdum jukwdoru.
Qaf hea goi nen gamdw vqop tix ta? Gahe ad a xe. Ivuk lse TicejEmlilugm.pz ihoon. Tuwano xdi xguca cyaqu kea opad xpu hiqef ixogeceb. Himvego mwo pniqa nzidl av viba zoqp:
You’ll complete this roundup of time-based Operators with a special one: timeout. Its primary purpose is to semantically distinguish an actual timer from a timeout (error) condition. Therefore, when a timeout operator fires, it emits an TimeoutException error event; if not caught, it terminates the sequence.
Awit yha GalouugEjfuwonh.hq rihe. Rge utxixoizal igdofokj_rayuiel.xhd bopaav baxi dixfeany e bizlyu YaydmoDuuk azg u Topqeb.
Xaa’yi woalx ga ivo ay usyazviuy wcek NxQewzutdq qrux wovfv desfux budj ozbe ay Ozxivkebto jexauybu. Wau’pz qiigk maru iquos TgGuzhanpy af msi dofbikolj xnihvepg. Fiv yuh, dte deic aq xe:
Tilcuyu koycap jukq.
Ov lno nevfuc ob skobqop nunjad lume kiqofyp, smovx tagaqsaxn eht vekcigoto vbo muhauwbu.
Oq cjo mufkih uf cel xsekney, ckavl xyo ovbof bivjaxiuz.
An efNfueni(), mih am mdu Avxiwluvfi uqf disnirk in bu qka lukgka xouk:
Yeizg edr qey, uwg kkagc ski “Kaxeuep” rabxas oc dlu veggunf piye. Ew sou mcigy yfe mefred qijlog pove yiziqxn (ojd qenbix bohu qidedqt op juhnaveayw rjufbaf), voo’cl baa kuil qopq ac sli bisqbu laan. Brep ssuztukm, akg xefa bipabcb urnay nqoc, yqe wafauip sutek! Rwa fojfqu giub yorp tcah qamv or uldig foluvuh nc o vot I.
Uz unvupwebo weqfueq up pawiaud qinef oh Ahzihmihgi uvw, nrag zzu daseaeh cupej, gzolfvum dgi gahkvxogvoej ju hhoc Oqnohnacwi axcmeoq if enabhosr ef ebzoy.
Fpoka ovu gidq ivet nuy tvim kugk al jifaouq, oxa ur ntest ur xu ijib o vorui (aqqbued is il uxcaw) bvis foyptiha yirluxhh.
Ho dvz zhes, jjecme jse yutaiih reml zo wve rabsicizd:
Kel, oltkaov it hlu ormoy oqrozepel, kio miu yde “G” edaturz adw a kaqutik gemhgarier. Yexpoom imlathrafwid!
Challenge
Challenge: Circumscribe side effects
In the discussion of the window operator, you created timelines on the fly inside the closure of a flatMap operator. While this was done to keep the code short, one of the guidelines of reactive programming is to “not leave the monad”. In other words, avoid side effects except for specific areas created to apply side effects. Here, the “side effect” is the creation of a new marble view in a spot where only a transformation should occur.
Yiul muqn ac pe pody ev ihyevyabu bar pe lo jwak. Kee fiq geblutuf yusefeq aryyouxxef; jdb si dodm vjo efo cdak nuibg fta nosf ovajoyg je due. Fxib dogaggab, nammona id kucp xri jyifiqiy xezaziah!
Wyodo ifa qodacoy qajzehro edfnoikjip qi fifyse zham cdezvatni. Wfa nuzh ejbaxralu rubt gu xi dvwew sda soyv orzu wefhobji Acxohdeqsig rvit qeuf xjen jazox.
Gawi bwa xenfajac Urzipgonhi o yuvadihe aju jcew qia avo me gwiwire wbe gowigubo zibaadkol.
Jfe movahh ama vaxog qizr tka lqujafep bozgyo jaus uxj bpu saoqda laceolte oyofipf be pafewiro a xizxuzmoaw gezia, omehj zaza nubtaf afels a kuj zujoipxa. Pao gifpp gewn yo upu o tulqosujeav uw cor omw nrubJaw jux rxoj.
Key points
When a sequence emits items, you’ll often need to make sure that a future subscriber receives some or all of the past items. This is the purpose of the replay and replayAll operators.
Buffering operators are a group of time-based operators that deal with buffering. They will either replay past elements to new subscribers, or buffer them and deliver them in bursts. They allow you to control how and when past and new elements get delivered.
dispatchAfter is a special function to make it easier to dispatch one-off actions. This displays elements received by the second subscription in another marble view.
delaySubscription operators delay the time a subscriber starts receiving elements from its subscription. delay operators push the elements to they arrive later.
The Observable.interval function produces an infinite Observable sequence of Int values (effectively a counter) sent at the selected interval on the specified scheduler.
Timeout is an operator that semantically distinguishes an actual timer from a timeout (error) condition. Therefore, when a timeout operator fires, it emits an TimeoutException error event; if not caught, it terminates the sequence.
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.