Angular 2 сервис с observable

Новый Angular 2 и выше использует очень интересную штуку — библиотеку rxjs.

С помощью нее можно просто реализовать паттерн Издатель-подписчик (publisher-subscriber, pub/sub) — это одна из реализаций паттерна  Observable.
То есть у нас есть Наблюдаемый объект (издатель), об изменении которого мы хотели бы узнавать в разных частях программы.  Поэтому мы на него подписываемся.

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

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

В rxjs для этого используется Subject. Это такой особенный наблюдатель, отличающийся от обычного тем, что позволяет не только подписываться на себя и рассылать , но может и принимать сообщения от подписчиков.

Subject vs BehaviorSubject

Но нам нужно, что в подписчиках мы могли получить не только то значение, которое пришло после подписки, но и то, что могло придти до того как мы подписались. То есть нужно сохранение последнего значения, которое было выпущено.

Поэтому мы используем BehaviorSubject, а не обычный Subject. С помощью него мы можем получить текущее значение, где бы не произошла подписка.

Для того, чтобы было понятно, немного примеров:

А теперь с BehaviorSubject:

Observable в сервисе Angular

Что ж с необходимыми знаниями rxjs разобрались, теперь рассмотрим как pub/sub паттерн  будет реализован в Angular сервисе. Код представлен на TypeScript и на самом деле работает на Angular 4, но думаю на Angular 2 он точно такой же:

Promise vs Observable

Возможно не совсем понятно чем лучше Observable по сравнению с promise. По сути это вообще функция, которая связывает издателя и подписчиков. При реализации некоторого функционала она работает лучше, чем promise.

Это хорошо видно на примере поиска — когда юзер вводит одну буквы, то мы сразу отправляем запрос на сервер. А в этот момент юзер уже стер ту букву, так что наш предыдущий запрос вообще уже не нужен.
Если реализация через Observable, то мы можем одной командой отменить этот запрос.

Также promise обрабатывает только одно событие, а Observable создает поток событий, для каждого из которых свой callback. Вообще Observable довольно похож на массив, соответственно и есть аналогичные методы, например, map.

То есть Observable — это promise с дополнительными бонусами.

На этом все, но вопросы крайней приветствуются!
Также очень вероятно, что вам будет интересно почитать про связку Angular и Redux — тема исторически является продолжением этого поста Angular-redux в примерах.

Полезные ссылки

Мануал rxjs
3 metaphors that show the power of the Observable
Talk on RxJs and Observables by @BenLesh

Хотите быть в курсе новых статей?

  1. первые 4 абзаца реально дали понять общую картину, что за зверь этот Observable
    А то на всех сайтах лезут сразу в глубь, а что оно и с чем едят не объясняют
    Спс большое