Это в большей степени конструктор, чем учебное пособие. Прочитав код, вы вряд ли его запомните. Лучше добавить или поменять в этом коде что-то на свой лад.
Вот список того, что ещё предстоит реализовать, и к чему вы сами можете приложить руку:
- 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)
- Платный курс, который можно посмотреть за время бесплатного доступа. Главное вспомнить отвязать банковскую карту до его окончания. Из этого курса я взял список операторов и их группировку.
- Примеры операторов RxJs. Не все рабочие.
- Графические примеры операторов RxJs
- ReactiveX документация
- RxJs документация
По ходу дела я прикрутил в проект два линтера и несколько наборов правил:
- сорян, но табы. Они позволяют настраивать каждому своё отображение, не меняя код в репе.
- именование файлов в шашлычном стиле
- именование интерфейсов с префиксом
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(). Отдельно указываем какой именно оператор закончил тестирование, чтобы быстрее ловить другие ошибочно не закоментированные операторы
);