BACK
Use casesLoad state machine — idle/loading/success/error
Use cases · 43

Load state machine — idle/loading/success/error

Паттерн

Каждый async-запрос проходит через явные состояния: loadingsuccess(data) или error(message). Это discriminated union — типизированная state machine, а не три раздельных boolean.

Какую проблему решаем

Раздельные поля isLoading, data, error легко рассогласовать. После failure кто-то забыл сбросить data, и UI показывает старые данные с error-баннером сверху. Невозможные комбинации флагов плодятся как сорняки.

Операторы и зачем они нужны

  • startWith({kind: 'loading'}) — сразу эмитим loading-состояние, ДО ответа.
  • map(data => ({kind: 'success', data})) — успешный ответ становится success-state.
  • catchError(error => of({kind: 'error', error})) — failure становится error-state, БЕЗ падения outer stream.

Подводные камни

  • tap с ручными флагами this.isLoading=true/false — труднее тестировать, чем state-as-data.
  • catchError снаружи trigger-stream — одна ошибка остановит все будущие reload. Ставьте ВНУТРИ switchMap.
  • Не смешивайте idle и loading. idle = «запроса ещё не было». loading = «запрос летит». Это разные состояния.

Что в итоге получаем

UI получает один типизированный state и рендерит его через switch. Невозможных комбинаций больше нет.

script.ts // TypeScript
CONSOLE · Console Output
Нажмите на запуск, чтобы увидеть результат...