октябрь 10, 2017 · angular angular-cli

RxJS 5 Lettable Operators и Angular CLI 1.4.9+

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

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

import 'rxjs/add/operator/takeUntil';
import 'rxjs/add/operator/pluck';
import 'rxjs/add/operator/filter';

stream
  .takeUntil(...)
  .pluck(...)
  .filter(...)
  .subscribe();

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

import { takeUntil, pluck, filter } from 'rxjs/operators';

stream
  .pipe(
      takeUntil(...),
      pluck(...),
      filter(...),
  )
  .subscribe();

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

Зачем?

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

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

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

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

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

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

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

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.

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

  • LinkedIn
  • Tumblr
  • Reddit
  • Google+
  • Pinterest
  • Pocket