RxJS Π Π΅Π°ΠΊΡ‚ΠΈΠ²Π½ΠΎΡΡ‚ΡŒ

RxJs ВСория: Observable, Observer, Subscription, Pipe

Observable - конструктор источника событий Observer - ΡΠ»ΡƒΡˆΠ°Ρ‚Π΅Π»ΡŒ событий, создаСт источник событий ΠΏΡƒΡ‚Π΅ΠΌ подписки

Π’Π°ΠΊΠΎΠΉ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ ΠΏΠΎΠ΄Ρ€Π°Π·ΡƒΠΌΠ΅Π²Π°Π΅Ρ‚ ΠΏΠΎΠ΄ собой созданиС конструктора событий Observable, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΠΎΠ΄ΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‚ΡΡ ΡΠ»ΡƒΡˆΠ°Ρ‚Π΅Π»ΠΈ событий. Π’ свою ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ, сами ΡΠ»ΡƒΡˆΠ°Ρ‚Π΅Π»ΠΈ событий

Promise ΡƒΠΆΠ΅ сам являСтся источником события. Он Π²Ρ‹Π·Π²Π°Π½ ΠΈ ΠΌΠΎΠΆΠ΅Ρ‚ Π²Ρ‹Π΄Π°Ρ‚ΡŒ Π»ΠΈΠ±ΠΎ ΠΎΡˆΠΈΠ±ΠΊΡƒ, Π»ΠΈΠ±ΠΎ ΡƒΡΠΏΠ΅ΡˆΠ½Ρ‹ΠΉ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚. Π’Π°ΠΊ ΠΆΠ΅ Π½Π° Π½Π΅Π³ΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠ΄ΠΏΠΈΡΠ°Ρ‚ΡŒΡΡ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ then, Ссли Π±ΡƒΠ΄Π΅Ρ‚ успСх ΠΈΠ»ΠΈ reject, Ссли Π²Ρ‹Π»Π΅Π·Π΅Ρ‚ ошибка

Π£ нас Π² ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ Π΅ΡΡ‚ΡŒ Ρ‚Ρ€ΠΈ Observable, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‚ΡΡ, ΠΊΠΎΠ³Π΄Π° срабатываСт Observer. Π’Π°ΠΊ ΠΆΠ΅ Observable ΠΌΠΎΠ³ΡƒΡ‚ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ Π΄Ρ€ΡƒΠ³ Π΄Ρ€ΡƒΠ³Π° Ρ‡Π΅Ρ€Π΅Π· pipe, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒΡΡ Π΄Ρ€ΡƒΠ³ Π·Π° Π΄Ρ€ΡƒΠ³ΠΎΠΌ

ΠœΡ‹ Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ события Ρƒ ΠΎΠ±Π·Ρ‘Ρ€Π²Π΅Ρ€Π° Ρ€ΠΎΠ²Π½ΠΎ Π΄ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΏΠΎΠΊΠ° ΠΎΠ½ Π½Π΅ Π·Π°ΠΊΠΎΠ½Ρ‡ΠΈΡ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ ошибкой ΠΈΠ»ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ΠΌ запроса. Π”Π°Π»ΡŒΡˆΠ΅ ΡƒΠΆΠ΅ события Π½Π΅ Π±ΡƒΠ΄ΡƒΡ‚ Π΄ΠΎΡ…ΠΎΠ΄ΠΈΡ‚ΡŒ Π΄ΠΎ ΠΎΠ±Π·Ρ‘Ρ€Π²Π΅Ρ€Π°.

Observer.next - ΠΌΠ΅Ρ‚ΠΎΠ΄ для получСния ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π³ΠΎ события Observer.error - ΠΌΠ΅Ρ‚ΠΎΠ΄ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ ошибки источника событий Observer.complete - ΠΌΠ΅Ρ‚ΠΎΠ΄ для выполнСния дСйствий Π½Π° Π·Π°ΠΊΡ€Ρ‹Ρ‚ΠΈΠΈ источника событий

Pipe - процСсс Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΡ конструктора источника события Pipe ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹ - чистыС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ

Π’ качСствС ΠΏΠ°ΠΉΠΏΠ°, ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ Π·Π°Π΄Π°Ρ‚ΡŒ Ρ‚ΠΎΡ‚ ΠΆΠ΅ Ρ„ΠΈΠ»ΡŒΡ‚Ρ€, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΡ‚ΡΠ΅ΠΈΠ²Π°Ρ‚ΡŒ Π½Π΅Π²Π°Π»ΠΈΠ΄Π½Ρ‹Π΅ запросы Π½Π° сСрвСр

1. Как Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ RxJS

Основной ΠΈΠ΄Π΅Π΅ΠΉ Ρ€Π°Π±ΠΎΡ‚Ρ‹ RxJS являСтся подписка Π½Π° ΠΎΠΏΡ€Π΅Π΄Π΅Π»Ρ‘Π½Π½Ρ‹Π΅ события ΠΈ Ρ€Π΅Π°Π³ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π½Π° Π½ΠΈΡ….

ΠšΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎ Π² ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ ΠΌΡ‹ создаём подписку, которая Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€ΠΈΡ‚ подписанныС Π½Π° Π½Π΅Ρ‘ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Ρ€Π°Π· Π² сСкунду.

Π§Π΅Ρ€Π΅Π· subscribe ΠΌΡ‹ подписываСмся Π½Π° эмиттСр события ΠΈ выполняСм ΠΊΠΎΠ΄ Ρ€Π°Π· Π² ΠΎΠΏΡ€Π΅Π΄Π΅Π»Ρ‘Π½Π½ΠΎΠ΅ врСмя.

import { Component } from '@angular/core';
import { interval } from 'rxjs';
 
@Component({
	selector: 'app-root',
	templateUrl: './app.component.html',
	styleUrls: ['./app.component.scss'],
})
export class AppComponent {
	constructor() {
		const intervalStream$ = interval(1000);
 
		intervalStream$.subscribe((value) => {
			console.log(value);
		});
	}
}

2. ΠžΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡ стримов

Если ΠΌΡ‹ Π½ΠΈΠΊΠ°ΠΊ Π½Π΅ Π±ΡƒΠ΄Π΅ΠΌ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΈ ΠΎΡ‚ΠΊΠ»ΡŽΡ‡Π°Ρ‚ΡŒ стримы, Ρ‚ΠΎ Ρƒ нас ΠΎΠ½ΠΈ Π±ΡƒΠ΄ΡƒΡ‚ постоянно Π°ΠΊΡ‚ΠΈΠ²Π½Ρ‹ ΠΈ постоянно ΠΊΠΎΠΏΠΈΡ‚ΡŒΡΡ. ΠŸΡ€ΠΎΡˆΠ»Ρ‹ΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ постоянно, ΠΏΠΎΠΊΠ° страница Π°ΠΊΡ‚ΠΈΠ²Π½Π°.

Π§Ρ‚ΠΎΠ±Ρ‹ ΠΈΡΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ Π΄Π°Π½Π½ΡƒΡŽ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡƒ, ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠΎΡ…Ρ€Π°Π½ΠΈΡ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ стрима Π² ΠΏΠΎΠ»Π΅ с Ρ‚ΠΈΠΏΠΎΠΌ Subscription, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠΌΠ΅Ρ‚ΡŒ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΎΡ‚ΠΏΠΈΡΠ°Ρ‚ΡŒΡΡ ΠΎΡ‚ стрима Ρ‡Π΅Ρ€Π΅Π· unsubscribe()

import { Component } from '@angular/core';
import { interval, Subscription } from 'rxjs';
 
@Component({
	selector: 'app-root',
	templateUrl: './app.component.html',
	styleUrls: ['./app.component.scss'],
})
export class AppComponent {
	sub: Subscription;
 
	constructor() {
		const intervalStream$ = interval(1000);
 
		this.sub = intervalStream$.subscribe((value) => {
			console.log(value);
		});
	}
 
	stop() {
		this.sub.unsubscribe();
	}
}

Кнопка Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ срабатываниС ΠΌΠ΅Ρ‚ΠΎΠ΄Π° остановки ΠΈΠ½Ρ‚Π΅Ρ€Π²Π°Π»Π°

<div class='container'>
	<h1>RxJS</h1>
	<button class='btn' (click)='stop()'>Stop Interval</button>
</div>

И Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ ΠΊΠ½ΠΎΠΏΠΊΠ° останавливаСт ΠΈΠ½Ρ‚Π΅Ρ€Π²Π°Π»

3. Как ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹

Π’ RxJS присутствуСт ΠΎΠ³Ρ€ΠΎΠΌΠ½ΠΎΠ΅ мноТСство ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠ², ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠ³ΡƒΡ‚ Ρ€Π°Π·Π½Ρ‹ΠΌΠΈ способами ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅ ΠΈ сам стрим

Π§Π΅ΠΉΠ½ pipe() ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Π² сСбя ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΈ Π±ΡƒΠ΄ΡƒΡ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ Π½Π°Π΄ нашими Π΄Π°Π½Π½Ρ‹ΠΌΠΈ

ΠšΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎ Π² Π΄Π°Π½Π½ΠΎΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ Π² ΠΏΠ°ΠΉΠΏ ΠΏΠΎΠΏΠ°Π΄Π°Π΅Ρ‚ Π΄Π²Π° ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π°, ΠΈΠ· ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ…:

  • filter - Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ΡƒΠ΅Ρ‚ проходящиС дальшС Π΄Π°Π½Π½Ρ‹Π΅
  • map - видоизмСняСт Π΄Π°Π½Π½Ρ‹Π΅
import { Component } from '@angular/core';
import { interval, Subscription } from 'rxjs';
import { map, filter } from 'rxjs/operators';
 
@Component({
	selector: 'app-root',
	templateUrl: './app.component.html',
	styleUrls: ['./app.component.scss'],
})
export class AppComponent {
	sub: Subscription;
 
	constructor() {
		const intervalStream$ = interval(1000);
 
		this.sub = intervalStream$
			.pipe(
				filter((value) => value % 2 === 0),
				map((value) => `Mapped ${value}`),
			)
			.subscribe((value) => {
				console.log(value);
			});
	}
 
	stop() {
		this.sub.unsubscribe();
	}
}

И Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ Ρƒ нас выходят Π² консоль Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‡Ρ‘Ρ‚Π½Ρ‹Π΅ Π·Π°ΠΌΠ°ΠΏΠ»Π΅Π½Π½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅

4. Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ своСго стрима

ΠœΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ свой стрим с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ класса Observable. Π’Π½ΡƒΡ‚Ρ€ΡŒ Π½Π΅Π³ΠΎ ΠΌΡ‹ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‘ΠΌ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Ρ‘Π½Π½ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ, Π²Π½ΡƒΡ‚Ρ€ΠΈ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡ‚ΡŒ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ ΠΏΠΎΡ‚ΠΎΠΊΠ°

ΠšΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎ ΠΌΡ‹ ΠΈΠΌΠ΅Π΅ΠΌ Ρ‚Ρ€ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄Π°:

  • next - Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€ΠΈΡ‚ срабатываниС ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ ΠΊΠΎΠ»Π»Π±Π΅ΠΊΠ° Π²Π½ΡƒΡ‚Ρ€ΠΈ subscribe
  • complete - ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ запрос Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ (ΠΈ Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€ΠΈΡ‚ Ρ‚Ρ€Π΅Ρ‚ΠΈΠΉ коллбэка)
  • error - Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ ΠΎΡˆΠΈΠ±ΠΊΡƒ Π²Π½ΡƒΡ‚Ρ€ΠΈ ΠΎΠ±Π·Ρ‘Ρ€Π²Π΅Ρ€Π° (ΠΈ Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€ΠΈΡ‚ Π²Ρ‚ΠΎΡ€ΠΎΠΉ коллбэка)

Π’Π°ΠΊ ΠΆΠ΅ ΠΌΠ΅Ρ‚ΠΎΠ΄ subscribe() Ρƒ стрима ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Ρ‚Ρ€ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‚ΡΡ ΠΏΠΎ Π²Ρ‹Π·ΠΎΠ²Ρƒ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΈΠ· Ρ‚Ρ€Ρ‘Ρ… состояний Π²Π½ΡƒΡ‚Ρ€ΠΈ ΠΎΠ±Π·Π΅Ρ€Π²Π΅Ρ€Π°

import { Component } from '@angular/core';
import { Subscription, Observable } from 'rxjs';
 
@Component({
	selector: 'app-root',
	templateUrl: './app.component.html',
	styleUrls: ['./app.component.scss'],
})
export class AppComponent {
	sub: Subscription;
 
	constructor() {
		const stream$ = new Observable((observer) => {
			setTimeout(() => {
				observer.next(1);
			}, 1500);
 
			setTimeout(() => {
				observer.complete();
			}, 1900);
 
			setTimeout(() => {
				observer.error('Something went wrong');
			}, 2000);
 
			setTimeout(() => {
				observer.next(2);
			}, 2500);
		});
 
		this.sub = stream$.subscribe(
			(value) => console.log(`Next: ${value}`), // next
			(error) => console.log(`Error: ${error}`), // error
			() => console.log('Complete'), // complete
		);
	}
 
	stop() {
		this.sub.unsubscribe();
	}
}

5. Как Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Subject

Класс Subject позволяСт ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ стрим, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌΡƒ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€ΠΎΡ‚ΠΈΠΏΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅ΠΌΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΈ ΠΎΠΏΠΈΡΠ°Ρ‚ΡŒ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΠ΅ΠΌΡƒΡŽ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ Π½Π°Π΄ Π΄Π°Π½Π½Ρ‹ΠΌ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠΌ

Π‘ ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° next ΠΌΡ‹ Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€ΠΈΠΌ срабатываниС коллбэка

import { Component } from '@angular/core';
import { Subscription, Subject } from 'rxjs';
 
@Component({
	selector: 'app-root',
	templateUrl: './app.component.html',
	styleUrls: ['./app.component.scss'],
})
export class AppComponent {
	sub: Subscription;
	stream$: Subject<number> = new Subject<number>();
	counter: number = 0;
 
	constructor() {
		this.sub = this.stream$.subscribe((value) => {
			console.log('Subscribe', value);
		});
	}
 
	stop() {
		this.sub.unsubscribe();
	}
 
	next() {
		this.counter += 1;
		this.stream$.next(this.counter);
	}
}

Π’Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ ΠΌΠ΅Ρ‚ΠΎΠ΄

<div class='container'>
	<h1>RxJS</h1>
	<button class='btn' (click)='stop()'>Stop Interval</button>
	<button class='btn btn-danger' (click)='next()'>Next value</button>
</div>

И Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€ΠΈΡ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ, которая Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒΡΡ ΠΏΠΎ сабскрайбу