2.06M
Категория: ПрограммированиеПрограммирование

Observables. Creation Operators

1.

Observables. Creation Operators

2.

Agenda
Основные концепции RxJs (англ)

3.

4.

https://rxjs.dev/guide/overview
Философия Observable
(docs) Observables are lazy Push collections of multiple values
Push-стратегия распространения изменений (В pull-системах "потребитель"
решает, когда получить данные от "поставщика")
(docs) Observables are able to deliver values
either synchronously or asynchronously.

5.

Observable is LAZY
(docs)
«Subscribing to an
Observable is
analogous to
calling a Function»

6.

Отличия от Promise
1)
Observable может эмитить несколько значений (>=0), а Promise только
одно (1)
2)
Observable – lazy, то есть вычисляет значение только после явного
subscribe (= computation does not start until subscription. Promises execute
immediately on creation)
var promise = $.get('https://www.google.com');
3) Observable позволяет отменить подписку (unsubscribe), а Promise выполнит
действие, даже если результат уже не требуется
https://angular.io/guide/comparing-observables

7.

https://rxjs.dev/guide/observer
Что надо добавить в конструктор Observable
Объект, принимаемый конструктором Observable, реализует интерфейс с тремя
методами: next, error, complete
const observable = new Observable((subscriber: Subscriber) => {
subscriber.next(1);
setTimeout(() => {
subscriber.next(4);
subscriber.complete();
//subscriber.error(‘someError’);
}, 1000);
});
1, 2, 3 – поставляются синхронно, 4 - асинхронно

8.

Что делает subscribe
const observer: Observer = {
next: x => console.log('Observer got a next value: ' + x),
error: err => console.error('Observer got an error: ' + err),
complete: () => console.log('Observer got a complete notification'),
};
observable.subscribe(observer);
NB: observable.subscribe(console.log);

9.

https://medium.com/ngx/why-do-you-need-unsubscribe- https://rxjs.dev/guide/subscription
ee0c62b5d21f
Что возвращает subscribe: Subscription
• unsubscribe()
• add()
• remove()
Вызов unsubscribe() нужен только для
бесконечно исполняемых Observable,
иначе занимаемые ими ресурсы будут
освобождены только с окончанием
работы всего приложения. А значит в
процессе работы программы может
произойти утечка памяти или могут
быть
созданы
ненужные
дублирующиеся "потребители".

10.

Не забывайте освобождать ресурсы в custom
infinite Observable!
(in order to avoid wasting computation power or memory resources)
const timer = new Observable(observer => {
let counter = 0;
const intervalId = setInterval(() => {
observer.next(counter++);
}, 1000);
return () => {
clearInterval(intervalId);
}
});
const subscription = timer.subscribe({next: console.log});
setTimeout(() => subscription.unsubscribe(), 5000); //поток завершится через 5 секунд
https://talohana.com/blog/rxjs-and-angular-unsubscribe-like-a-pro

11.

How to create Observable

12.

Of /From
WARNING: ‘of’ does NOT flatten arrays without “…”
GOOD WARNING: ‘from’ DOES flatten arrays (Maps / strings /
Promises / iterable objects

13.

range
1 число – с чего начинаем (fractions allowed)
2 число – сколько чисел будет

14.

interval
Emits incremental numbers periodically in time.
emits an infinite sequence
1000 = через 1000 мс новое значение (первое
тоже)
const numbers = interval(2000);

15.

timer = delay of start
Создает задержку (use timer to delay subscription to an observable by a set
amount of time)
По дефолту эмитит 0, поэтому нужно использовать, например, concatMap (use
concatMap to provide your own Observable)
В качестве аргумента принимает number (мс) или объект Date. Если указан
только один аргумент, то эмит будет единственным
Второй (необязательный аргумент) – интервал между эмитами
Можно использовать в takeUntil
timer(1000).pipe(concatMap(() => someObservable))

16.

EMPTY
EMPTY.subscribe({
next: () => console.log('Next'),
complete: () => console.log('Complete!')
});
Когда юзать: фильтрация значений в mergeMap / concatMap / switchMap.
It can be used for composing with other Observables, such as in a mergeMap.
https://blog.novanet.no/rxjs-getting-fooled-by-empty-observables/

17.

18.

NEVER
This may be useful in very limited cases where you need to return a value, but you don’t
want subscribers to act on it
If you want to return a value and call all subscribers, then you must use
Of(value).
If you want to return a value and *not* call subscribers, then use
EMPTY.
If you subscribers not only act on emit, but also on completion and you
want to avoid this behaviour, use NEVER.
https://upmostly.com/angular/empty-vs-never-vs-of-in-rxjs-angular

19.

generate: работает как цикл for

20.

throwError
const errorWithTimestamp$ = throwError(() => {
const error: any = new Error(`This is error number ${ ++errorCount }`);
error.timestamp = Date.now();
return error;
});

21.

ajax: creates an observable for an Ajax request
getJson(): даёт нужные данные из объекта
response, а не весь объект

22.

fromEvent: реагируем на события пользователя
const clicksInDocument = fromEvent(document, 'click');
Дополнительные
параметры:
Once: true = take(1)
Capture: true
Passive: true
https://learn.javascript.ru/bubbling-and-capturing

23.

https://rxjs.dev/api/index/function/fromEventPattern
fromEventPattern
Creates an Observable from an arbitrary API for registering event handlers.
Similar to fromEvent, but far more flexible.
https://xgrommx.github.io/rxbook/content/observable/observable_methods/fromeventpattern.html

24.

25.

iif: как if else, но есть нюанс…
Checks a boolean at subscription time and chooses between one of two observable sources
https://tyapk.ru/blog/post/rxjs-iif-feature

26.

defer: ничего не делаем, пока кто-то не
подпишется
It waits until an Observer subscribes to it, calls the given factory function to get an
Observable
Код внутри defer выполнится только при подписке, а не во время создания
Пример использования: отсрочка Promise
var promise = $.get('https://www.google.com');
(The promise in this case is already executing before any handlers have been connected.)
https://stackoverflow.com/questions/3876457
8/rxjs-understanding-defer
https://habr.com/ru/articles/492948/

27.

bindCallback: функция, а не оператор
• third party code
• Argument: function f(x, callback). Return: function g that when called as g(x) will output an
Observable.
• Функция f (например ajax-request) будет отрабатывать, только если на g(x) будут
подписываться
• Дает 1 эмит и потом комплитится
https://gistlib.com/javascrip
t/how-to-use-thebindcallback-function-fromthe-rxjs-library-in-javascript
https://stackoverflow.com
/questions/41202873/wha
t-is-the-differencebetween-bindcallbackand-bindnodecallback-inrxjs-api

28.

bindNodeCallBack: Node.js-style
• It's just like bindCallback, but the callback is expected to be of type callback(error, result)
• Can be used in non-Node.js environments as well
• provides convenient error handling
https://rxjs.dev/api/index/function/bindNodeCallback

29.

To be continued…

30.

Источники
https://softchris.github.io/books/rxjs/
RxJs для самых маленьких
RxJs in Depth (youtube, Eng)
RxJs по косточкам (youtube, Rus)
https://tinytip.co/
English     Русский Правила