RxJS

Реактивный подход в разработке

...

async await!

Парадигмы программирования

Императивная (контрастирует с декларативной)

  • Процедурная
  • Структурная
  • Аспектно-ориентированная
  • Объектно-ориентированная
    • Агентно-ориентированная
    • Компонентно-ориентированная
    • Прототипно-ориентированная
  • Обобщённое программирование

Декларативная (контрастирует с императивной)

  • Чистота языка
    • Чистота функции
  • Функциональная
    • В терминах Рефал-машины
    • Аппликативная
    • Комбинаторная
    • Бесточечная
      • (чистая конкатенативная)
  • Логическая
  • Конкатенативная
  • Векторная
  • Метапрограммирование
    • Языково-ориентированная
      • Предметно-ориентированная
      • Пользователями
  • Методы и алгоритмы
    • Автоматное
    • Динамическое
    • Потоков данных
    • Событийно-ориентированное
    • Реактивное
    • Сервис-ориентированное

Грамотное/литературное программирование (Literate Programming)

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

Давайте изменим традиционные приоритеты в создании программ: вместо представления о нашей задаче как о создании инструкций «Что делать?» для компьютера сконцентрируемся на объяснении другим людям описаний нашего видения того, что под управлением программы должен делать компьютер.
— Дональд Кнут

Реактивное программирование

Парадигма, ориентированная на потоки данных и распространение изменений.

Реактивные подходы к программированию

Императивное реактивное программирование

Императивные программы могли бы работать над реактивными структурами данных.

Объектно-ориентированное реактивное программирование

Вероятно, наиболее естественный способ сделать это состоит в том, что вместо методов и полей, у объектов есть реакции, которые автоматически пересчитывают значения и другие реакции зависят от изменений этих значений.

Функциональное реактивное программирование

Является наиболее естественным базисом для реализации реактивной архитектуры, хорошо сочетаясь с параллелизмом.

1997. Fran.

Conal Elliott and Paul Hudak

Fran is a collection of data types and functions for composing richly interactive, multimedia animations.

b1 `until` e => b2

вести себя как b1 до возникновения события e, после этого вести себя как b2.

Реализации в JS:

  • Bacon.js
  • Cycle.js
  • Elm
  • Kefir
  • RxJS

Reactive Revolution

ReactiveX is more than an API, it's an idea and a breakthrough in programming. It has inspired several other APIs, frameworks, and even programming languages.

Языки

ReactiveX для платформ и фреймворков

RxJS

Set of libraries to compose asynchronous and event-based programs using observable collections and Array#extras style composition in JavaScript

Observable, Observer, Subscriber, Operators

Observable — это объект или функция, которая выдает последовательности данных во времени.

Observer — это объект или функция, которая знает, как обрабатывать последовательности данных.

Subscriber — это объект или функция, которая связывает Observable и Observer.

Operators — это функции, которыми можно преобразовывать данные между моментом, когда Observable их отправил, и моментом, когда подписчик их получил.

Observable

Создание observable


var observable = Rx.Observable.create(function (observer) {
  observer.next(1);
  observer.next(2);
  observer.next(3);
  setTimeout(() => {
    observer.next(4);
    observer.complete();
  }, 1000);
});
							

Создание observable из event


window.onload = function() {
  var button = document.querySelector('button');
  
  var observable = Rx.Observable.fromEvent(button,  'click');
  
  observable.subscribe((event) => {
    console.log('Observable: ', event);
  });

  button.addEventListener('click', (event) => {
    console.log('Event listener: ', event);
  });
}
							

Подписка на observable


observable.subscribe(
  (x) => console.log('got value ' + x),
  (err) => console.error('something wrong occurred: ' + err),
  () => console.log('done')
);
							

Observables можно создать на:

  • Array
  • Array-like object (e.g. DOM elements)
  • Event
  • Iterable object
  • Observable-like
  • Promise

Cold vs hot observable

Producer (изготовитель) - это некоторый поток, который генерирует данные и передает их в observable.

Cold observable

  1. Создает producer
  2. Активирует producer
  3. Начинате слушать producer
  4. индивидуальный (unicast)

Hot observable

  1. ссылается producer
  2. Начинате слушать producer
  3. многоадресный (multicast)
Cold observable [ng2]

const source = new Observable((observer) => {
  const socket = new WebSocket('ws://someurl');
  socket.addEventListener('message', (e) => observer.next(e));
  return () => socket.close();
});
							


Hot observable

const socket = new WebSocket('ws://someurl');
const source = new Observable((observer) => {
  socket.addEventListener('message', (e) => observer.next(e));
});
							

Примеры операторов

concat

когда важен порядок вывода последовательностей.


const getPostOne$ = Rx.Observable.timer(3000).mapTo({id: 1});
const getPostTwo$ = Rx.Observable.timer(1000).mapTo({id: 2});

Rx.Observable
	.concat(getPostOne$, getPostTwo$)
	.subscribe(res => console.log(res));
						

forkJoin

аналог Promise.all()


const getPostOne$ = Rx.Observable.timer(1000).mapTo({id: 1});
const getPostTwo$ = Rx.Observable.timer(2000).mapTo({id: 2});

Rx.Observable
	.forkJoin(getPostOne$, getPostTwo$)
	.subscribe(res => console.log(res))
						

mergeMap

чтобы все элементы внутренние Observable порождали событие основного.


const post$ = Rx.Observable.of({id: 1});
const getPostInfo$ = Rx.Observable
	.timer(3000).mapTo({title: "Post title"});

const posts$ = post$
	.mergeMap(post => getPostInfo$)
	.subscribe(res => console.log(res));
						

pairwise

возвращает не только текущее значение, но в месте с ним и предыдущее значение последовательности


// Tracking the scroll delta
Rx.Observable
  .fromEvent(document, 'scroll')
  .map(e => window.pageYOffset)
  .pairwise()
  .subscribe(pair => console.log(pair)); // pair[1] - pair[0]
						

Еще несколько примеров операторов

map

filter

scan

do

withLatestFrom

combineLatest

Interactive diagrams of Rx Observables

links

Спасибо! Вопросы?