← Назад к вопросам

Что такое Cold Observable?

2.2 Middle🔥 121 комментариев
#Архитектура и паттерны

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Cold Observable в RxJS

Определение

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

Как это работает

В Cold Observable каждый вызов .subscribe() запускает новое независимое выполнение источника данных. Это означает, что если у вас есть два подписчика, они получат одинаковую последовательность, но запущенную дважды:

import { Observable } from 'rxjs';

const coldObservable = new Observable((observer) => {
  console.log('Observable запустился');
  observer.next(1);
  observer.next(2);
  observer.next(3);
  observer.complete();
});

// Первый подписчик
coldObservable.subscribe((value) => {
  console.log('Подписчик 1:', value);
});
// Вывод:
// Observable запустился
// Подписчик 1: 1
// Подписчик 1: 2
// Подписчик 1: 3

// Второй подписчик
coldObservable.subscribe((value) => {
  console.log('Подписчик 2:', value);
});
// Вывод:
// Observable запустился (запустилось заново!)
// Подписчик 2: 1
// Подписчик 2: 2
// Подписчик 2: 3

Практические примеры Cold Observable

HTTP запросы

HTTP запросы в Angular/RxJS являются Cold Observable:

import { HttpClient } from '@angular/common/http';

const request$ = this.http.get('/api/users');

// Первая подписка — запрос отправится
request$.subscribe((data) => {
  console.log('Данные 1:', data);
});

// Вторая подписка — запрос отправится ЕЩЕ РАЗ
request$.subscribe((data) => {
  console.log('Данные 2:', data);
});

Здесь каждая подписка создает новый HTTP запрос.

Timer

import { timer } from 'rxjs';

const timer$ = timer(1000, 1000);

// Подписка 1
timer$.subscribe((value) => {
  console.log('Подписчик 1:', value);
});

// Подписка 2 (будет считать независимо)
setTimeout(() => {
  timer$.subscribe((value) => {
    console.log('Подписчик 2:', value);
  });
}, 500);

Проблема: множественные подписки

Cold Observable может привести к проблемам при множественных подписках:

const coldRequest$ = this.http.get('/api/users');

// Плохо: 3 отдельных запроса
coldRequest$.subscribe(data => this.users = data);
coldRequest$.subscribe(data => this.count = data.length);
coldRequest$.subscribe(data => this.loading = false);

Решение: Hot Observable с shareReplay

Для избежания множественных выполнений используется оператор shareReplay(), который превращает Cold Observable в Hot Observable:

import { shareReplay } from 'rxjs/operators';

const users$ = this.http.get('/api/users').pipe(
  shareReplay(1)
);

// Все три подписки используют ОДИН запрос
users$.subscribe(data => this.users = data);
users$.subscribe(data => this.count = data.length);
users$.subscribe(data => this.loading = false);

Различие Cold vs Hot

Cold Observable - начинает выполнение при подписке, каждый получает свою последовательность. Hot Observable - выполняется независимо, все получают одну последовательность.

Выводы

Cold Observable — это стандартное поведение в RxJS. Важно понимать эту особенность, чтобы избежать случайного выполнения кода и уметь преобразовать Cold в Hot при необходимости с помощью операторов вроде shareReplay() или share().