A .Net Reaktív Kiterjesztés olyan funkciókat kínál a fejlesztőknek, amelyek reaktív programozási modellt valósítanak meg a .Net fejlesztők számára, hogy az eseménykezelés egyszerűbbe és kifejezőbbe tegye deklaratív műveletek segítségével. Bár a reaktív skálázás kulcsfontosságú alapkövei az IObserver és IObservable interfészek, fejlesztőként gyakran nem kell ezeket magadnak megvalósítanod. A könyvtár támogatja a beépített Subject típust<T>, amely interfészeket valósít meg és számos funkciót támogat.
A témák képezik az alapot a könyvtárban elérhető különböző témákhoz, és vannak más témák is – ReplaySubject<T>,<T> BehaviorSubject és <T>AsyncSubject. Hasznos megérteni a lényeges különbségeket közöttük, és megérteni, hogyan lehet ezeket felhasználni a könyvtár jobb kihasználásához.
Ebben a cikkben összehasonlítjuk az Alany<T> és testvérét, hogy szemléltessenük a viselkedésük közötti különbségeket.
Tárgy<T>
Ahogy korábban említettük, a Subject<T> az elérhető témák alapja, így egyszerű módot biztosít a könyvtár használatára anélkül, hogy magadnak kellene megvalósítanod az IObservable<T> és IObserver<T> interfészeket. Az alábbiakban a téma típusának egyszerű bemutatása látható.
A fenti kódban létrehoztunk egy <T>Subject példányt, és mivel az<T> IObserver és IObserverable <T>implementálja, ugyanazt az példányt használjuk az érték előfizetéséhez és közzétételéhez az IObserveren. Egy másik fontos szempont, hogy a Subscribe metódus túlterhelését használjuk fel az akciók bemeneti bemeneti elfogadására. Ezt minden közzétett értékre megteszedjük, ebben az esetben a számot a konzolra nyomtatva.
Próbáljuk meg megmutatni a közzétett értékeket és azokat az értékeket, amelyeket az IObserver (ebben az <T>akcióban) a konzolra nyomtat a következő képen. Ez segít könnyen összehasonlítani a megmaradt testvéreket és a változatokat.
Az első sor a közzétett értéket jelöli, a második sor pedig az IObserver által kapott értéket. Ezen felül hozzáadtunk egy sort, amely jelzi, hogy a megfigyelő mikor iratkozik fel a streamre a végrehajtás során. Ezt a vonalat egy függőleges szaggatott vonal ábrázolja.
A fenti kódban azt vettük észre, hogy a megfigyelő előfizetést adott az adatfolyamra, mielőtt közzétette volna az első értéket. A képen az előfizető vonal látható, amely az első elem előtt helyezkedik el. Ahogy a kimeneti vonalról is láthatod, ez jelenleg nem befolyásolja a kimenetet.
De mi van, ha a megfigyelő csak akkor írja elő az adatokat, miután néhány értéket már közzétettek? Ez hatással van a megfigyelők által kapott adatokra? Mielőtt megnéznénk a kimenetet, először ugyanazt a kódot írjuk.
A fenti kódban megfigyelhetjük, hogy a megfigyelő csak akkor írja elő az adatfolyamot, miután két értéket (1 és 2) publikálnak. Ahogy várható lehet, ez azt eredményezi, hogy a megfigyelők nem kapják meg a közzétett adatokat az előfizetési módszer behívása előtt. Ahogy az alábbi ábrán látható.
Mi van, ha az összes közzétett értéket el akarod olvasni, még akkor is, ha a megfigyelő későn iratkozik elő? Itt jön képbe a ReplaySubject<T>.
ÚjrajátszásTéma<T>
A ReplaySubject<T> gyorsalogos értékeket gyűjt, és későbbi előfizetők számára újrajátszik. Ez hasznos a versenykörülmények elkerüléséhez. Változtassuk meg az előző kódot a<T> ReplaySubject-re, és nézzük meg, hogyan befolyásolja, amit a megfigyelő kap.
Ahogy a fenti kódban is látható, alig<T> <T>változik a kódban, kivéve, hogy most már a ReplaySubject kifejezést használjuk a subject helyett. Az alábbi ábra szemlélteti a megfigyelő által kapott adatokra gyakorolt hatást.
Ahogy a képen látható, a gyorsítótározott értéket most már visszajátszik az előfizető számára, még akkor is, ha az előfizető később előfizet. Természetesen ennek a hasznos funkciónak ára van. Ez a megvalósítás minden előfizető által közzétett értéket gyorsítótárba helyez, ami súlyos memóriaproblémákat okozhat, ha az adatmennyiség jelentősen nagyobb.
Azonban a<T> ReplaySubject-nek több módja van ennek a problémának a megoldására. A példa kedvéért két példát nézünk meg, amelyek méret- és időkorlátokat használnak a gyorsítótározott érték korlátozására.
Első esetben a cache méretét használjuk a cache értékének korlátozására. <T>A ReplaySubject konstruktora túlterhelést biztosít, amely egy egész számot fogad el, amely a gyorsítótár puffer méretét (maximális elemszámot) képviseli. A példánkban módosítsuk a kódot, hogy a gyorsítótár méretet 1-re korlátozzuk.
Figyeld meg, hogyan <T>használjuk a ReplaySubject konstruktor túlterhelését, hogy a Cache méretét 1-ként adjuk meg. Ez korlátozza a gyorsítótárat, és biztosítja, hogy csak egy elemet gyorsítsanak fel, majd új elemmel helyettesítsenek a publikáció megjelenése után. A változás hatását az alábbiakban bemutatjuk.
Egy másik módja a gyorsítótár korlátozásának, ha korlátozzuk a gyorsítótározott elem idejét, vagyis lejárati időt biztosítunk a gyorsítótározott elemnek.
Írjunk kódot ennek a példának a szemléltetésére.
Hasonlóan az előző kódhoz, a<T> ReplaySubject konstruktor túlterhelését használjuk a gyorsmérőben lévő elemek lejárati idejének meghatározására. Állításunk bemutatására késleltetést vezettünk be az értékek kiadása között.
Mivel teljes 1200 ms időbe telik, mire a megfigyelő feliratkozik, minden olyan elem, amely meghaladja a 1000 ms lejárati időt, eltávolítják a gyorsítótárból. Ebben a példában ez az 1-es érték eltávolítását eredményezi a gyorsítótárból, és nem lesz újrajátszva a késői előfizetőknek. Ahogy az alábbi ábrán látható.
<T>Vannak más túlterhelések a ReplaySubject számára, amelyek nagyobb rugalmasságot biztosítanak és finomhangolják a gyorsabőrös értékeket, de például a fent említett két példát megtartjuk.
ViselkedésSubject<T>
A BehaviourSubject <T>nagyon hasonlít a<T> ReplaySubject-re, abban a szempontból, hogy segít az értékek gyorsatárában tárolni. De van egy jelentős különbség. BehaviourSubject<T> csak az utolsó közzétett értéket gyorsanyázza. Mielőtt tovább mennénk ebbe, írjunk egy kis kódot.
Ha a BehaviorSubject<T> csak egyetlen értéket gyorsatároz (ami utoljára ismert), miben számít az 1 méretű <T>ReplaySubject-től? A következő diagram egyértelműen tükrözi a fenti kód helyzetét.
Ez azonban nem teljesen igaz. Két fontos különbséget kell megérteni. Az első a alapértelmezett tényezők jelenléte. Megjegyzendő, hogy a fenti kódban <T>a BehaviourSubject konstruktorában alapértelmezett értékként 0 értéket adunk meg. Ha nincs érték a gyorsítótárban (vagyis nem jelent meg adat a megfigyelő előfizetése előtt), akkor az alapértelmezett értéket visszaállítják. Ez eltér a ReplaySubject-től, amelynek mérete 1<T>, és annak nincs értéke. A következő kód és a sorozat vizuális ábrázolása ezt a viselkedést mutatja.
A második különbség az, hogy a BehaviorSubject<T> és a ReplaySubject<T> hogyan viselkednek, amikor egy befejezett szekvenciára feliratkoznak. Amikor a befejezés után feliratkozik, a BehaviorSubject <T> nem lesz értékes, ahogy az alábbi kódban is látható.
Az előfizetők garantáltan nem kapnak értéket, mert az előfizetések a befejezés után következnek be.
Ez <T>azonban így van a ReplaySubject esetében. Nincs garancia arra, hogy a megfigyelő nem kap értékeket, ahogy az alábbi kódban látható.
Ahogy a fenti kódban látható, a gyorsítótár mérete 1, és még ha az előfizetést a hívás befejezése után is hívják, a cache megmarad (amíg a lejárati feltétel be nem teljesül), tehát ebben az esetben az utolsó közzétett érték megérkezik.
AsyncSubject<T>
Az AsyncSubject <T>az Subject utolsó testvére, akit ebben a cikkben vizsgálunk<T>, és nagyon hasonló az előző kettőhöz (ReplaySubject és BehaviourSubject), mivel eredményeket is gyorsalogász. De ismét jelentős különbség van. Az AsyncSubject csak akkor teszi közzé az utolsó gyorsgyorsított értéket, ha a sorozat teljesnek van <T> jelölve (csak egy értéket, az utolsó értéket gyorsanyáztat).
Vegyük a következő kódot.
Ez egy olyan értéket generál a megfigyelő számára, hogy a sorozat az utolsó közzététel értékként van megjelölve a befejezés előtt – 4-es érték. Ahogy az alábbi ábrán látható.
De mi történik, ha kihagyjuk azt a hívást, amely befejezettnek jelöli a sorozatot? Írjuk ki a sort, és próbáljuk újra.
Ez nem generál adatot a megfigyelő számára, mert az AsyncSubject<T> csak akkor teszi közzé az eredményeket, amikor a sorozat teljesnek van jelölve.
Ez egy jelentős különbség, amit minden AsyncSubject-et <T>használó ember szem előtt tart.
következtetés
Ez a cikk <T>bemutatja a Subject különböző testvérei és néhány változata közötti különbségeket. Gyakran hasznos tudatában lenni ezeknek a finom különbségeknek, mert ha nem veszed észre, másképp mutathatnak viselkedést, mint amire számítottál.
Eredeti link:A hiperlink bejelentkezés látható.
|