A megfigyelhetők angolul Observables.
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.
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:
<!DOCTYPE html> <html lang="hu"> <head> <meta charset="UTF-8"> <title>RxJS példa</title> </head> <body> <h1>Valami</h1> <script src="rxjs.umd.min.js"></script> <script src="app.js"></script> </body> </html>
JavaScriptből, így elérhető az rxjs objektum, amelyből most az interval() függvényt használjuk:
const { interval } = rxjs; const numbers = interval(5000); numbers.subscribe({ next: res => { console.log(res); } })
Az Angular projektekben TypeScriptet használunk, így másként kell az importálást végrehajtani.
const { interval } = rxjs; const { take, map } = rxjs.operators; const numbers = interval(1000); const fif = numbers.pipe( take(5), map( res => Date.now()) ) fif.subscribe({ next: res => { console.log(res); } })
Eredmény:
0 1 2 3 4
const { interval } = rxjs; const { take, map } = rxjs.operators; const numbers = interval(1000); const fif = numbers.pipe( take(5), map( res => Date.now()) ) fif.subscribe({ next: res => { console.log(res); } })
1681415031971 1681415032970 1681415033970 1681415034970 1681415035970
A from() metódus segítségével egy többő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); } })
8 16 12 4 14
Ha feliratkozunk egy Observable objektum értékeire, három metódust kapunk vissza.
Metódusok:
A három metódus leírása:
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
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 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);
Ha az 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. Az 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.