Programowanie reaktywne

Programowanie reaktywne jest to programowanie asynchroniczne oparte na obserwacji strumienia danych. W pierwszej kolejności wykorzystywane jest do obsługi zapytań HTTP, ale również może obsługiwać zdarzenia, odczytywać elementy tablic, itp. Framework Angular2 wykorzystuje bibliotekę RxJs, która z kolei wykorzystuje obiekt Observable.
Observable porównać można do Promise, który również wykorzystywany jest do obsługi HTTP. Istnieje kilka różnic pomiędzy Observable, a Promise.

Observable vs Promise

OBSERVABLE PROMISE
Umożliwia pracę z wieloma wartościami Zwraca pojedynczą wartość
Można go anulować Nie można go anulować
Oferuje wiele rozszerzeń dzięki RxJs

RxJs – wybrane metody

Obiekt RxJs Observable może reprezentować wiele asynchronicznych strumieni z danymi, do którego to obiektu należy się zasubskrybować subscribe. Wcześniej jednak RxJs oferuje wiele metod, dzięki którym możemy manipulować strumieniem danych na wiele sposobów. Poniżej lista najciekawszych metod, a następnie przykłady użycia (Observable + metody + subscribe).

  • .filter((value:number) => value % 2 === 0 ) – filtruje dane przychodzące zgodnie ze wzorem (w tym wypadku przepuszcza liczby parzyste)
  • .delay(500) – opóźnia działanie
  • .startWith(0) – rozpoczyna od podanej wartości
  • .distinctUntilChanged() – wstrzymuje działanie do momentu, aż nie będzie zmiany
  • .timestamp() – dodaje indywidualny znacznik godzinowy
  • .last() – przepuści tylko ostatni element
  • .first() – tylko pierwszy element
  • .find(x => x < 5 ) – tylko pierwszy element, który spełni warunek
  • .elementAt(4) – element, którego pozycja została wskazana w nawiasie
  • .skip(3) – przeskakuje liczbę wskazanych pozycji począwszy od 1
  • .take(2) – pobiera liczbę wskazanych pozycji począwszy od 1
  • .max() – wskazuje max pod warunkiem końca strumienia
  • .min() – wskazuje min pod warunkiem końca strumienia
  • .every(x => x > 0) – typ boolean sprawdza czy wszystkie elementy spełniają warunek dla zakończonego strumienia
  • .average(function (x) { return x.value }) – wskazuje średnią wartość, ale typ Observable musi być liczbą
  • .toArray() – zwraca wynik jako tablicę
  • .debounceTime(2100) – czeka wskazany czas zanim zadziała (pomocne w opóźnianiu zapytań np. oczekiwanie na kilka kliknięć lub na szybkie wpisanie w input)
  • .flatMap(x => [x]) – spłaszcza zagnieżdżone observable do jednego płaskiego
  • .map(x => x.value + ‚ TS:’ + x.timestamp) – zamienia każdy z obiektów przychodzących przez zastosowanie funkcji (przykład powiązany z .timestamp)
  • .map(x => Number(x)+10 ) – drugi łatwiejszy przykład użycia często stosowanej metody .map

Przykłady w Angular2

Przy pierwszym kontakcie z dokumentacją RxJs możemy spotkać się z problemem, ponieważ w dokumentacji wskazany jest następujący sposób na dołączenie tej biblioteki import Rx from 'rxjs/Rx';. Jeżeli pojawi się błąd: has no default export, jego rozwiązaniem jest: import * as Rx from 'rxjs/Rx';


Pierwszy przykład:

ngOnInit() {
    let counter = 1;
    let stream = new Observable(observer => {
      setInterval(() => {
              observer.next(counter++);
          },1000);
      setInterval(() => {
          observer.complete(); //observer zostaje zakończony po wskazanym czasie
          },10100);            //w rezultacie otrzymuje 10 liczb od 1 do 10
    });
    stream
    .filter((value:number) => value > 2 )
    .map(x => Number(x)+10 )
    .subscribe(value => console.log(value));

W wyniku działania otrzymamy w konsoli liczby od 13 do 20 ponieważ wynik jednych metod wpływa na kolejne, które znajdują się poniżej.


Drugi przykład

W pliku nazwa.component.html umieszczamy pole input oraz reakcję na klawisz ENTER:

< input type="text" (keyup.enter)="addArray(temp)" [(ngModel)]="temp">

następnie w pliku nazwa.component.ts właściwy Observable

import { Component, OnInit } from '@angular/core';
import * as Rx from 'rxjs/Rx';
import { Observable } from 'rxjs';
export class NazwaComponent implements OnInit {
 constructor() {
   }
 table = [1, 4, 7, 8, 10];
 data;
 addArray = function(newData) {
    this.table.push(newData);
    this.data = Rx.Observable.from(this.table)
    .filter((value:number) => value % 2 === 0 )
    .delay(500) 
    .distinctUntilChanged() //wstrzymuje do momentu, aż nie będzie zmiany
    .subscribe(x => console.log(x));
  }

W rezultacie ze wskazanym opóźnieniem otrzymamy w konsoli liczby parzyste 4, 8, 10 oraz te, które zostały wpisane przez użytkownika i były parzyste.


Trzeci przykład

Najbardziej użyteczny przykład. Na jego bazie możemy robić zapytania typu GET.

import {Http, Response} from '@angular/http';

searchAlbums = function(url) {
    this.http.get(url)
    .subscribe((response:Response)=>{
       let data = response.json()
       console.log(data);
    })
};

Nie pojawiła się tutaj nazwa Observable tak jak w powyższych przykładach, jednak wystarczy w Visual Code Studio najechać myszą na instrukcję get i zobaczymy, że tutaj również mamy do czynienia z Observable.

RxJs - Observable

Kontynuując przeglądanie strony, wyrażasz zgodę na używanie przez nas plików cookies. dowiedz się więcej

Aby zapewnić Tobie najwyższy poziom realizacji usługi, opcje ciasteczek na tej stronie są ustawione na "zezwalaj na pliki cookies". Kontynuując przeglądanie strony bez zmiany ustawień lub klikając przycisk "Akceptuję" zgadzasz się na ich wykorzystanie.

Zamknij