DEV.NVX.ME

Angular & TypeScript

RxJS Lettable Operators и Angular CLI 1.4.9+

| версия Angular: 4
rxjs-lettable-angular-cli.jpg

В @angular/[email protected] добавили поддержку [email protected] и вы можете попробовать новый механизм для управления потоками.

Раньше мы писали так:

1
2
3
4
5
6
7
8
9
import 'rxjs/add/operator/takeUntil';
import 'rxjs/add/operator/pluck';
import 'rxjs/add/operator/filter';
stream
.takeUntil(...)
.pluck(...)
.filter(...)
.subscribe();

А теперь можем так:

1
2
3
4
5
6
7
8
9
import { takeUntil, pluck, filter } from 'rxjs/operators';
stream
.pipe(
takeUntil(...),
pluck(...),
filter(...),
)
.subscribe();

Я не уверен, что есть устойчивый перевод для “lettable operator”. Буду благодарен за подсказку в этом вопросе.

Для того, чтобы попробовать новые возможности, нужно обновить Angular CLI и RxJS.

Зачем?

Импорт каждого оператора в каждом файле был необходим, чтобы не добавлять всю rxjs-либу в бандл. Основная проблема с цепочками вызовов, в невозможности использовать tree-shaking, для отсеивания неиспользуемого кода.

Если вы импортировали какой-то оператор и потом перестали его использовать, то это невозможно автоматически отследить линтерами или другими инструментами.

Также упростился механизм создание кастомных операторов.

Использование

Теперь операторы это просто функции с интерфейсом <T, R>(source: Observable<T>) => Observable<R>.

А в Observable добавлен метод pipe, который по-очереди применяет операторы.

Пример из официальной доки.

1
2
3
4
5
6
7
8
9
10
11
import { range } from 'rxjs/observable/range';
import { map, filter, scan } from 'rxjs/operators';
const source$ = range(0, 10);
source$.pipe(
filter(x => x % 2 === 0),
map(x => x + x),
scan((acc, x) => acc + x, 0)
)
.subscribe(x => console.log(x))

Создаем свой оператор

Возможность написать кастомный оператор была и раньше, но это требовало определенных усилий.

На примере из официальной доки, можно увидеть всю лаконичность нового API.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import { interval } from 'rxjs/observable/interval';
import { map, take, toArray } from 'rxjs/operators';
/**
* an operator that takes every Nth value
*/
const takeEveryNth = (n: number) => <T>(source: Observable<T>) =>
new Observable(observer => {
let count = 0;
return source.subscribe({
next(x) {
if (count++ % n === 0) observer.next(x);
},
error(err) { observer.error(err); },
complete() { observer.complete(); }
})
});
interval(1000).pipe(
takeEveryNth(2),
map(x => x + x),
takeEveryNth(3),
take(3),
toArray()
)
.subscribe(x => console.log(x));
// [0, 12, 24]

Обьявление оператора не создает сайд-эффектов, это просто функция, которую мы используем внутри метода pipe.


Больше информации в официальной доке: https://github.com/ReactiveX/rxjs/blob/master/doc/lettable-operators.md

Proudly powered by Hexo and Theme by Hacker
© 2018 Sasha Novik