Angular IDPStrong Junior
Модулі / Дані, моки й RxJS / Що таке Observable
🔥 0

Модуль 4 · урок 1 з 13

Що таке Observable

RxJS — це те, на чому спотикаються всі, хто приходить в Angular. Насправді вся складність тримається на одній ідеї: дані — це не значення, яке ти взяв, а потік, на який ти підписався. Якщо прийняти цю думку по-справжньому, решта модуля стає технікою.

Значення проти потоку

// значення: ти береш його, і воно є
const tasks = getTasks();
console.log(tasks.length);

// потік: ти кажеш, що робити, коли значення прийде
getTasks$().subscribe(tasks => console.log(tasks.length));

Різниця не в синтаксисі. Значення існує зараз і одне. Потік описує, що станеться з часом — і значень у ньому може бути нуль, одне або нескінченно багато.

Одне значенняБагато значень
СинхронноЗвичайна зміннаМасив
АсинхронноPromiseObservable

Ось і все місце Observable у картині світу: це масив, розтягнутий у часі.

Три канали

source$.subscribe({
  next:     value => console.log('значення', value),   // може статись багато разів
  error:    err   => console.error('помилка', err),    // один раз, потік закінчено
  complete: ()    => console.log('усе'),               // один раз, потік закінчено
});
УСПІШНИЙ ПОТІК next next next complete ПОТІК ІЗ ПОМИЛКОЮ error — далі нічого не буде
Значень може бути скільки завгодно, але завершення одне: або complete, або error. Після нього потік мертвий — це найважливіша деталь усього уроку.
Наслідок, який відчують усі

Помилка вбиває потік. Якщо в стрімі пошуку не обробити помилку, після першого ж невдалого запиту поле пошуку перестане працювати назавжди — і жодних повідомлень у консолі не буде. Це найпоширеніший баг новачків у RxJS, і урок 7 цілком про те, як його не зробити.

Лінивість: нічого не станеться без підписки

const request$ = this.http.get<Task[]>('/api/tasks');
// запиту ще НЕ БУЛО — це лише опис того, що станеться

request$.subscribe(tasks => …);   // ось тепер запит пішов

request$.subscribe(tasks => …);   // а це ДРУГИЙ запит, не той самий

Це головна відмінність від Promise. Проміс починає роботу в момент створення й запамʼятовує результат. Observable — це рецепт: скільки разів підписався, стільки разів він і виконається.

Холодні й гарячі потоки

ХолоднийГарячий
Коли починаєПри кожній підписціЖиве сам, незалежно від підписників
Що бачать підписникиКожен свою окрему копіюСпільні значення, з моменту підписки
Прикладhttp.get(), of()Події миші, WebSocket, Subject
АналогіяЗамовити фільм — почнеться спочаткуПрямий ефір — приєднався й дивишся з поточного моменту
// зробити холодний потік спільним, щоб запит пішов один раз на всіх
readonly tasks$ = this.http.get<Task[]>('/api/tasks').pipe(
  shareReplay({ bufferSize: 1, refCount: true })
);

shareReplay знадобиться, коли той самий потік читають кілька компонентів або кілька async pipe у шаблоні. Без нього кожен | async — це окремий HTTP-запит.

Observable проти Promise

PromiseObservable
Скільки значеньРівно однеСкільки завгодно
Коли стартуєОдразу при створенніПри підписці
СкасуванняНемаєunsubscribe()
Повторний запускНі, результат кешуєтьсяТак, кожна підписка заново
Операториthen, catchПонад сотня, комбінуються в pipe
Якщо спитають на дзвінку

«Observable — це потік значень у часі. На відміну від промайса, він лінивий: нічого не відбувається, поки не підпишешся, і кожна підписка запускає роботу заново. Його можна скасувати через unsubscribe, і до нього можна застосувати оператори. Помилка завершує потік назавжди, тому її треба ловити всередині pipe

≈ 45 хв · +25 XP за урок