Перейти к содержанию

RxJS Interop

Пакет RxJS Interop доступен для предварительного просмотра разработчиком. Он готов для того, чтобы вы могли попробовать, но он может измениться до того, как станет стабильным.

Пакет @angular/core/rxjs-interop от Angular, который предоставляет полезные утилиты для интеграции Angular Signals с RxJS Observables.

toSignal

Функция toSignal создает сигнал, который отслеживает значение Observable. Она ведет себя аналогично пайпу async в шаблонах, но является более гибкой и может быть использована в любом месте приложения.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
import { Component } from '@angular/core';
import { AsyncPipe } from '@angular/common';
import { interval } from 'rxjs';

@Component({
    template: `{{ counter() }}`,
})
export class Ticker {
    counterObservable = interval(1000);

    // Get a `Signal` representing the `counterObservable`'s value.
    counter = toSignal(this.counterObservable, {
        initialValue: 0,
    });
}

Как и пайп async, toSignal подписывается на Observable немедленно, что может вызвать побочные эффекты. Подписка, созданная toSignal, автоматически отписывается от данной Observable при уничтожении компонента, в котором вызван toSignal.

Начальные значения

Наблюдаемые могут не выдавать значение синхронно при подписке, но сигналы всегда требуют текущего значения. Существует несколько способов работы с этим "начальным" значением сигналов toSignal.

Опция initialValue

Как и в примере выше, опция initialValue определяет значение, которое сигнал должен вернуть перед первым испусканием Observable.

неопределенные начальные значения

Если опция initialValue опущена, сигнал, возвращаемый toSignal, возвращает неопределенное значение до тех пор, пока Observable не испустит сигнал. Это похоже на поведение пайпа async, возвращающей null.

Опция requireSync

Известно, что некоторые наблюдаемые испускаются синхронно, например, BehaviorSubject. В этих случаях вы можете указать опцию requireSync: true.

Когда requiredSync имеет значение true, toSignal принудительно обеспечивает синхронное испускание наблюдаемого сигнала при подписке. Это гарантирует, что сигнал всегда имеет значение, и не требуется никакого неопределенного типа или начального значения.

manualCleanup

По умолчанию toSignal автоматически отписывается от Observable при разрушении контекста, в котором он был создан. Например, если toSignal вызывается во время создания компонента, он очистит подписку, когда компонент будет уничтожен.

Опция manualCleanup отключает эту автоматическую очистку. Вы можете использовать эту настройку для Observables, которые завершают себя естественным образом.

Ошибка и завершение

Если Observable, используемая в toSignal, выдает ошибку, эта ошибка будет выброшена при чтении сигнала.

Если Observable, используемая в toSignal, завершается, сигнал продолжает возвращать последнее выданное перед завершением значение.

toObservable

Утилита toObservable создает Observable, который отслеживает значение сигнала. Значение сигнала отслеживается с помощью effect, который выдает значение Observable при его изменении.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
import { Component, signal } from '@angular/core';

@Component(...)
export class SearchResults {
  query: Signal<string> = inject(QueryService).query;
  query$ = toObservable(this.query);

  results$ = this.query$.pipe(
    switchMap(query => this.http.get('/search?q=' + query ))
  );
}

При изменении сигнала query наблюдаемая query$ выдает последний запрос и запускает новый HTTP-запрос.

Контекст инъекции

toObservable по умолчанию должен выполняться в контексте инъекции, например, во время создания компонента или сервиса. Если контекст инъекции недоступен, вместо него можно явно указать Injector.

Время выполнения toObservable

toObservable использует эффект для отслеживания значения сигнала в ReplaySubject. При подписке первое значение (если оно доступно) может быть испущено синхронно, а все последующие значения будут асинхронными.

В отличие от Observables, сигналы никогда не предоставляют синхронного уведомления об изменениях. Даже если ваш код обновляет значение сигнала несколько раз, эффекты, зависящие от его значения, выполняются только после того, как сигнал "успокоится".

1
2
3
4
5
6
const obs$ = toObservable(mySignal);
obs$.subscribe((value) => console.log(value));

mySignal.set(1);
mySignal.set(2);
mySignal.set(3);

Здесь будет зарегистрировано только последнее значение (3).

Комментарии