[[oktatas:web:javascript|< JavaScript]]
====== JavaScript - RxJS ======
* **Szerző:** Sallai András
* Copyright (c) 2023, Sallai András
* Szerkesztve: 2023, 2024
* Licenc: [[https://creativecommons.org/licenses/by-sa/4.0/|CC Attribution-Share Alike 4.0 International]]
* Web: https://szit.hu
===== A megfigyelhetők =====
A megfigyelhetők angolul Observables. Az RxJS egy programozói könyvtár, amely lehetővé teszi adatok megfigyelését, aszinkron kódok könnyű kezelését.
Az Observables, egy új primitív típus, ami lehetővé teszi, folyamok kezelését,
amelyekre előfizethetünk, reagálhatunk új értékekre stb.
A folyamokat kombinálhatjuk, amelyekből újabb folyamok készíthetők.
A kérdés az ECMAScript szabványba bekerül-e az Observables?
Amíg nincs benne az olyan könyvtárakat használhatjuk mint a RxJS.
Az RxJS a **Reactive Extensions for JavaScript** szavakból alkotott
betűszó, és egy olyan könyvtár, amit Observables-t biztosít
JavaScript nyelven.
A megfigyelők lusták. Addig nem termelnek adatokat, amíg fel nem iratkozunk azokra.
* subscribe() - Feliratkozás az adatfolyamra.
* unsubcribe() - Leiratkozás az adatfolyamról.
===== NodeJS projektben =====
npm init -y
npm install rxjs
npm install --save-dev lite-server
Készítsünk egy bs-config.json fájlt, a lite-server számára, így használhatjuk a node_modules/rxjs/dist/bundles/ könyvtár állományait, úgy mintha egy könyvtárban
lennének az src könyvtár állományaival:
{
"server": [
"src",
"node_modules/rxjs/dist/bundles"
]
}
A HTML fájlban a rxjs.umd.min.js fájlt csatoljuk:
RxJS példa
Valami
JavaScriptből, így elérhető az rxjs objektum, amelyből most az interval() függvényt használjuk:
const { interval } = rxjs;
/* 5 másodpercenként egy szám kibocsájtása */
const numbers = interval(5000);
/* Feliratkozás az adatfolyamra */
numbers.subscribe({
next: res => {
console.log(res);
}
})
Az Angular projektekben TypeScriptet használunk, így másként kell az importálást végrehajtani.
===== Take operátor =====
Az adatfolyam átalakítása.
const { interval } = rxjs;
const { take } = rxjs.operators;
/*
Az interval() egy Observable objektumot hoz létre,
ami másodpercenként egy új számot bocsájt ki
*/
const numbers = interval(1000);
/*
A take operátorral korlátozzuk, hogy csak az
első 5 értéket kapjuk meg.
A teke() operátorokat a pipe() függvénnyel
tudjuk használni.
*/
const fif = numbers.pipe(
take(5)
)
/*
A subscribe() függvénnyel feliratkozunk az adatfolyamra.
A paraméterben leírjuk, hogy mit történjen az érkező értékkel.
*/
fif.subscribe({
next: res => {
console.log(res);
}
})
Eredmény:
0
1
2
3
4
===== Map =====
A következő példában két operátorral is belenyúlunk az adatfolyamba.
const { interval } = rxjs;
const { take, map } = rxjs.operators;
const numbers = interval(1000);
/*
A map(res => Date.now()) átalakítja az eredetileg kibocsájtott
értéket, a kibocsájtás időbélyegét adja vissza.
*/
const fif = numbers.pipe(
take(5),
map( res => Date.now())
)
fif.subscribe({
next: res => {
console.log(res);
}
})
1681415031971
1681415032970
1681415033970
1681415034970
1681415035970
===== From =====
A from() metódus segítségével egy tömbből megfigyelhető objektumot készítünk:
const { from } = rxjs;
const { map } = rxjs.operators;
from([4, 8, 6, 2, 7])
.pipe(map(res => res * 2))
.subscribe({
next: res => {
console.log(res);
}
})
* A from() függvény létrehoz egy Observable objektumot.
* A map() függvény minden értéket felszoroz 2-vel.
* A subscribe() függvénnyel feliratkozunk az eredményre.
8
16
12
4
14
===== Az Observable metódusai =====
Ha feliratkozunk egy Observable objektum értékeire, három metódust kapunk vissza.
Metódusok:
* next
* error
* complete
A három metódus leírása:
* A next() akkor hajtódik végre, amikor megérkezik a következő adat.
* A error() hiba esetén.
* A complete() ha befejeződött az adatfolyam.
const { from } = rxjs;
from([1, 2, 3, 4, 5])
.subscribe({
next: res => {
console.log(res);
},
error: err => {
console.log(err);
},
complete: res => {
console.log('kész')
}
})
Kimenet
1
2
3
4
5
kész
===== fromEvent =====
Feliratkozás eseményre.
const { fromEvent } = rxjs;
const goButton = document.querySelector('#goButton');
const observer = {
next: res => {
console.log(res);
},
error: err => {
console.log(err);
},
complete: res => {
console.log('kész')
}
}
const observable = fromEvent(goButton, 'click');
observable.subscribe(observer);
Leirtkozás
const observable = fromEvent(goButton, 'click');
//Valamikor később, leiratkozhatunk az eseményről.
const subscription = observable.subscribe(observer);
subscription.unsubscribe();
===== A Subject =====
A Subject egy speciális megfigyelő típus. Lehetővé teszi egyszerre több
érték küldését.
A következő példában két Observer van egy Subject-hez kapcsolva.
const Subject = rxjs.Subject;
sub = new Subject();
sub.subscribe({
next: res => console.log('A', res)
})
sub.subscribe({
next: res => console.log('B', res)
})
sub.next(1);
sub.next(2);
===== A Promise és az Observable =====
Ha a Promise-on keresztül benyújtunk egy kérelmet, akkor
biztosak lehetünk abban, hogy ugyanarra a kérésre nem érkezik
több válasz. A Promise a feloldó függvénynek elsőnek átadott értékkel
véget ért, figyelmen kívül hagyja a további hívásokat.
Ezzel szemben az Observable lehetővé teszi több érték
feloldását mindaddig, amíg meg nem hívjuk az observable.complete()
függvényt.
A Promise objektumok tervezésüknél fogva buzgók. A Promise konstruktor
meghívása után azonnal elkezdi végrehajtani a megadott feladatot.
Ezzel szemben az Observable addig nem hajtódik végre, amíg
valaki fel nem iratkozik rá.
A Promise kérés lemondását az ES6 még nem támogatja. Ha
ilyet szeretnénk, a bluebird vagy az axios programozói
könyvtárakat használhatjuk.
Az Observable esetén eltárolhatjuk a feliratkozást
egy Subscription objektumban, amin keresztül leiratkozhatunk
az unsubscribe() függvénnyel.
===== Linkek =====
* https://codecraft.tv/courses/angular/reactive-programming-with-rxjs/observables-and-rxjs/ (2023)
* https://dev.to/sagar/reactive-programming-in-javascript-with-rxjs-4jom (2023)
* https://indepth.dev/posts/1114/learn-to-combine-rxjs-sequences-with-super-intuitive-interactive-diagrams (2023)