Как узнать, если switchMap отписался от внутреннего Observable?
Поскольку switchMap
может отрезать (отписаться) внутреннюю заметку, если появится новый элемент, мы ожидаем следующее:
const items = from([1, 2])
const seen = []
const derived = items.pipe(
switchMap(item =>
concat(
of(`now: ${item}`),
of(`end: ${item}`).pipe(delay(10))
)
)
)
derived.subscribe(next => seen.push(next))
привести к seen
имеющий:
['now: 1', 'now: 2', 'end: 2']
^ unsubscribed to 1 here, as planned!
Вопрос в том, есть ли способ получить уведомление об отмене пункта 1? Причина в том, что если отмены происходят слишком часто, я бы хотел знать.
Я пробовал способы изменения внутренних Observables, но в основном все, что я пытаюсь сделать "в конце" их просто не происходит, когда отписался. Спецификация Observer имеет next
, completed
, а также error
, но ничего для "закончилась рано", так что я не уверен, что попробовать.
Я хотел бы иметь возможность передать дополнительную функцию в switchMap, которая будет вызываться оператором, когда внутренняя наблюдаемая отменяется, и предоставляет аргумент.
const derived = items.pipe(
switchMap(item => concat(
of(`now: ${item}`),
of(`end: ${item}`).pipe(delay(10))
),
(item) => console.error(`${item} was cut off.`))
)
1 ответ
Изменить: на странице RxJS GitHub есть проблема, обсуждающая эту функцию для finalize
оператор. https://github.com/ReactiveX/rxjs/issues/2823
поскольку switchMap
отписывает внутренний Observable, он не получит никакого полного уведомления.
Вместо этого вы можете просто добавить обработчик удаления или просто использовать finalize()
оператор, который делает это для вас, и он вызывается, когда цепочка ликвидирована. Это касается как полных, так и неподписных событий.
switchMap(item =>
concat(
of(`now: ${item}`),
of(`end: ${item}`).pipe(delay(10))
).pipe(
finalize(() => /* switchMap unsubscribed or concat completed */),
)
)
Обратите внимание: когда вы отписываетесь, это означает, что вы больше не хотите получать предметы из Обсерватории. Это означает, что вы не можете получать какие-либо новые предметы из отписавшегося Observable при отписке. Есть например defaultIfEmpty
оператор, который испускает элемент, когда источник завершает работу, не испуская ничего, что работает для полных уведомлений, но не может работать, вы просто отменили подписку.