Хук отписки RxJS

Имея фрагмент кода, который извлекает некоторые данные в кеш и синхронизирует их с помощью соединения через веб-сокет, а также предоставляет интерфейс доступа к данным с помощью Observable, как я могу знать, что в какой-то момент нет подписчиков на указанные данные во время?

Я хотел бы подключиться к вызову unsubscribe() для наблюдаемого (и проверить, равно ли количество подписчиков 0), но я не уверен, как этого добиться.

Сценарий реальной жизни — это запрос graphql (apollo-angular) и подписка на веб-сокет для синхронизации данных. Если нет подписчиков на данные (например, пользователь перешел на другую страницу), соединение через веб-сокет может быть закрыто для экономии ресурсов сервера, но данные необходимо одновременно удалить из кеша, иначе они могут уйти. не синхронизировано, поскольку с сервера больше не поступают push-события на случай, если пользователь снова вернется. Я не хочу хранить устаревшие данные в кеше.

Итак... Как я могу подключиться к событию, когда наблюдаемое уничтожается/все подписчики отписались, чтобы также удалить данные из кеша? Служба настраивает запрос graphql и настраивает подписку для прослушивания изменений, возвращая Observable, но я не уверен, как я могу разорвать это, поскольку экземпляр был передан в коде пользователя.

Я не ищу только сеть, обход кеша и подобные настройки клиента аполлона, я ищу способ реально использовать, но сохранить данные в кеше аполлона чистыми и актуальными, так как сервер предоставляет способ сделать это.


person Ákos Vandra    schedule 27.05.2020    source источник
comment
Не могли бы вы использовать refCount и Subject? Насколько вы контролируете наблюдаемый веб-сокет?   -  person NathanH    schedule 27.05.2020


Ответы (1)


Если вы используете RxJS, вы можете использовать WebSocketSubject, у которого есть несколько отличных опций.

Например, WebSocketSubject может быть задан объект конфигурации, где одной полезной опцией является closeObserver: NextObserver<T>, чей метод next вызывается, когда соединение сокета закрывается.

Соединение автоматически закрывается, когда у WebSocketSubject больше нет активных подписчиков.


Вот код для вышеупомянутой идеи:

const connectionClosed = new Subjet();
const unsubscribe = new Subject();

const webSocket = new WebSocketSubject({
  url: '',
  /* ... */,
  closeObserver: connectionClosed
});

connectionClosed.subscribe(() => {
  // Teardown logic
  // e.g clear cache 
});


// Registering subscribers
webSocket.pipe(takeUntil(unsubscribe)).subscribe(...);
webSocket.pipe(takeUntil(unsubscribe)).subscribe(...);
webSocket.pipe(takeUntil(unsubscribe)).subscribe(...);

// In `ngOnDestroy`, called maybe when the user navigates to another route
unsubscribe.next();
unsubscribe.complete();
person Andrei Gătej    schedule 27.05.2020