Skip to content

bskydive/rxjs-aj4vwd-stackblitz

Repository files navigation

Бибиотека операторов RxJs

Это в большей степени конструктор, чем учебное пособие. Прочитав код, вы вряд ли его запомните. Лучше добавить или поменять в этом коде что-то на свой лад.

Вот список того, что ещё предстоит реализовать, и к чему вы сами можете приложить руку:

  • TODO заполнить для всех примеров: запуск, результат, тэги, описание, аналоги, кэширует/теряет, стартует/конвеер, сохраняет порядок/сортирует
  • TODO сделать конфигуратор операторов: тип входных значений, выходных, преобразования, аналоги
  • TODO заменить жаргонизмы на точное обозначение "подписывается, имитирует, ..."(рытьё исходников)
  • TODO добавить ссылки на https://www.learnrxjs.io/ и https://rxmarbles.com/ в описания всех операторов
  • TODO привести примеры multicasting к массовому варианту запуска в index.ts
  • TODO заполнить примерами новый файл testing.ts https://medium.com/@kevinkreuzer/marble-testing-with-rxjs-testing-utils-3ae36ac3346a
  • TODO написать тесты для для всех примеров
  • TODO добавить в описания операторов их более простые аналоги/комбинации
  • TODO сделать вывод времени получения значений, чтобы подчеркнуть ждунирование .subscribe((item) => logAll('получил: ', timeNow(), item),
  • TODO проверить, что все .push и .subscribe строки содержат корректные имена переменных, можно пихнуть/подписаться на соседний оператор

Как использовать

  • примеры разбиты на файлы, чтобы не сводить с ума линтеры, и собраны в index.ts через экспорт массивов для реализации в будущем автотестов.
  • запуск всех примеров выключен(закомментирован). Чтобы их запустить - надо раскомментировать подписку subscribe
  • для генерации входного потока данных вручную сделана кнопка <button id="id-tight-button"> в index.html
  • можно открыть в IDE, а можно через chrome в облаке stackblitz
  • Необходимые операторы ищутся ctrl+f, в конце добавляем $ к названию оператора. Например switchMap$. Также операторы видны в "структуре кода" - специальном окне IDE.
  • Перед каждым примером есть небольшое описание и результат выполнения
  • В облаке stackblitz:
    • обновить страницу(stackblitz)
    • раскомментировать *$.subscribe(* строку необходимого оператора
    • открыть консоль встроенного браузера(stackblitz)
  • Локально в IDE:
    	git clone https://github.com/bskydive/rxjs-aj4vwd-stackblitz.git
    	cd rxjs-aj4vwd-stackblitz
    	npm i
    	npm run b
  • Список плагинов VSCode, которые относятся к теме:
  • чтобы заглушить ненужный входной поток достаточно дописать в начеле *.pipe(* оператор take(0)

Список основных ресурсов, на основе которых написана библиотека

Автоматическая проверка кода

По ходу дела я прикрутил в проект два линтера и несколько наборов правил:

  • сорян, но табы. Они позволяют настраивать каждому своё отображение, не меняя код в репе.
  • именование файлов в шашлычном стиле
  • именование интерфейсов с префиксом I
  • многие правила es/ts lint дублируются, часть отключено в одном из двух, но большинство оставлено, т.к. непонятно как конкретно работают правила, и непонятно что лучше.
  • правила форматирования переведены в severity: warn.
  • нельзя оставлять в коде console.log()
  • Финская нотация. Да, она через линтер помогает, например, не проглядеть тип значений внутри операторов map(item=>item... | map(item$=>item$... , т.к. вместо объекта может прилететь Observable, и это не всегда отлавливается tslint.
  • перелопатил все правила eslint, и добавил что добавилось. Искал правило для сложного случая, который периодически трепал мне нервы. Не нашёл :(.
  • rxjs-tslint-rules
  • codelyzer for Angular
  • angular-tslint-rules: a configuration preset for both TSLint & codelyzer
  • RxJS: Avoiding takeUntil Leaks
  • Best practices for a clean and performant Angular application

Виды операторов по типу операций со значеними

  • buffering.ts — Операторы буферизации buffer*, window*
  • erroring.ts — Операторы обработки ошибок
  • filtering.ts — Операторы фильтрации
  • grouping.ts — Операторы группировки потоков и значений
  • multicasting.ts — Операторы асинхронного запуска потоков(распыления)
  • testing.ts — Операторы тестирования. Не реализовано.
  • timing.ts — Операторы времени, продолжительности и значений
  • tooling.ts — Операторы вспоможения в трудах
  • transforming.ts — Операторы трансформации потоков и значений
  • utils.ts — Интерфейсы и служебные функции

Типовой пример

const auditProbe$ = item => { // функция-аргумент для передачи в оператор
	logAll('проверка: ' + item); // для отладки пишем полученное значение
	return interval(300).pipe(take(3)); // возвращаем наблюдатель. В данном случае - для имитации трёх значений. 
	//.pipe(take(X)) - хорошее правило для ограничения утечек памяти
}

const audit2$ = interval(102).pipe( // поток для отладки оператора
	take(10), // ограничиваем количество значений
	map(item => item * 102), // делаем значения человеко-понятными, выводим время их имитации в мсек, выбрали 102 вместо 100 чтобы не было случайных гонок асинхронных потоков(перестраховка)
	tap(logAll), // выводим сырые значения перед отправкой в недра исследуемого оператора
	audit(auditProbe$) // исследуемый оператор
)

const audit1$ = interval(101).pipe( // контрольный поток для сравнения, без оператора для исследования
	take(10),
	map(item => item * 101 + '-control'), // добавляем постфикс для облегчения чтения отладки
)

const audit$ = of(audit1$, audit2$).pipe( // одновременно запускаем два потока
	mergeAll(), // собираем значения потоков в один, "конвертируем" потоки в значения
);

//запускаем потоки и выводим всё в консоль. префиксы нужны, чтобы понимать, что значение долетело до конца
audit$.subscribe((item) => 
	logAll('получил: ', item), // пишем всё, что получили по сигналу next().
	err => logAll('ошибка:', err), // пишем что прилетело по сигналу error()
	() => logAll('audit поток закрыт') // пишем когда прилетело complete(). Отдельно указываем какой именно оператор закончил тестирование, чтобы быстрее ловить другие ошибочно не закоментированные операторы
);