Чем Observable отличается от Promise?angular-39

Основные отличия

Характеристика Observable Promise
Множественность значений Может излучать множество значений Возвращает только одно значение
Ленивость Выполняется только при подписке Выполняется сразу при создании
Отмена Поддерживает отмену (unsubscribe) Не поддерживает отмену
Композиция Богатые операторы (map, filter и др.) Только then/catch/finally
Синхронные вызовы Может излучать синхронно и асинхронно Всегда асинхронный

Подробное сравнение

1. Множественность значений

Observable может излучать множество значений с течением времени:

const observable = new Observable(subscriber => {
  subscriber.next(1);
  subscriber.next(2);
  subscriber.next(3);
  setTimeout(() => {
    subscriber.next(4);
    subscriber.complete();
  }, 1000);
});

observable.subscribe(value => console.log(value));
// Вывод: 1, 2, 3, (через 1 сек) 4

Promise всегда возвращает только одно значение:

const promise = new Promise(resolve => {
  resolve(1);
  // Последующие вызовы resolve игнорируются
  resolve(2);
});

promise.then(value => console.log(value)); // Вывод: 1

2. Ленивость выполнения

Observable "ленивый" — не выполняется до вызова subscribe:

const obs = new Observable(() => {
  console.log('Observable выполняется');
});

// Ничего не выведет, пока не вызван subscribe
obs.subscribe(); // Теперь выведет "Observable выполняется"

Promise выполняется немедленно при создании:

const prom = new Promise(() => {
  console.log('Promise выполняется');
});
// Сразу выведет "Promise выполняется"

3. Возможность отмены

Observable можно отменить:

const subscription = interval(1000).subscribe(console.log);
setTimeout(() => subscription.unsubscribe(), 3000); // Отмена после 3 сек

Promise нельзя отменить после создания:

const promise = fetch('/api/data');
// Нет стандартного способа отменить запрос

4. Композиция и операторы

Observable предоставляет мощные операторы:

import { map, filter, debounceTime } from 'rxjs/operators';

inputValueChanges.pipe(
  debounceTime(300),
  filter(text => text.length > 2),
  map(text => text.toUpperCase())
).subscribe(console.log);

Promise имеет только базовые методы:

fetch('/api/data')
  .then(response => response.json())
  .catch(error => console.error(error));

5. Обработка событий

Observable идеален для событий:

fromEvent(button, 'click').subscribe(() => {
  console.log('Кнопка нажата!');
});

Promise не подходит для повторяющихся событий.

Когда что использовать?

Используйте Promise когда:

  • Нужен единичный асинхронный результат
  • Простая цепочка операций
  • Работа с async/await синтаксисом

Используйте Observable когда:

  • Множественные значения с течением времени
  • Необходима отмена операций
  • Работа с событиями или потоками данных
  • Нужны сложные трансформации данных

Пример преобразования Promise в Observable

import { from } from 'rxjs';

const promise = fetch('/api/data');
const observable = from(promise);

observable.subscribe({
  next: response => console.log(response),
  error: err => console.error(err)
});

Обратное преобразование

import { firstValueFrom } from 'rxjs';

async function getData() {
  const data = await firstValueFrom(data$);
  console.log(data);
}

Резюмируем

Observable — это мощная абстракция для работы с асинхронными и событийными потоками данных, тогда как Promise предназначен для единичных асинхронных операций. В Angular Observable используются повсеместно (HTTP, Forms, Router), но в некоторых сценариях Promise может быть проще и уместнее. Понимание их различий позволяет выбирать правильный инструмент для каждой задачи.