В RxJS версии 5 следующий код приводит к завершению процесса после трех итераций обеих подписок:
var Rx = require("rxjs");
const published$ = Rx.Observable.interval(1000).publish();
published$.subscribe(index => {
console.log(`One: ${index}`);
if (index == 3) throw new Error("ded.");
});
published$.forEach(index => {
console.log(`Two: ${index}`);
});
published$.connect();
Однако я понял, что ошибка, выданная в следующем обработчике, просто отменит подписку на эту конкретную подписку и не приведет к прекращению действия базового наблюдаемого объекта. Я ожидал, что подписка «Одна» отменит подписку, но интервал продолжит давать результаты для подписки «Две».
Это поведение вызывает у меня проблемы, когда у меня может быть несколько подписок на базовый горячий наблюдаемый объект, но одно исключение, выброшенное на любую из этих подписок, приводит к полному прекращению основного наблюдаемого объекта.
Это особенно раздражает, когда я разрабатываю, использую горячую перезагрузку модуля, поскольку любая программная ошибка в любой подписке заставляет меня обновлять всю страницу, чтобы перезапустить наблюдаемые последовательности.
Есть ли способ, не заключая каждую из моих подписок в try / catch, чтобы в моем следующем обработчике было выброшено исключение, чтобы просто отменить подписку на эту ОДНУ подписку и не прервать базовую наблюдаемую?
------------ РЕДАКТИРОВАТЬ ------------
Я нашел поведение, которое ищу, установив для syncErrorThrowable значение true в объекте подписки, возвращаемом параметром subscribe. Кажется, что единственный раз, когда это когда-либо устанавливается в true в кодовой базе, это через оператор «do».
Стоит ли мне воспользоваться этим полем? Я чувствую себя довольно грязным, используя его, но, с другой стороны, мне кажется странным, что оператор «do» имеет другую семантику обработки ошибок, чем обработчик подписки «next».
Вот основной блок кода, на который влияет этот флаг: https://github.com/ReactiveX/RxJS/blob/master/src%2FSubscriber.ts#L132
Если установлено значение false, вызывается этот метод: https://github.com/ReactiveX/RxJS/blob/master/src%2FSubscriber.ts#L179
Если для него установлено значение true, вместо него используется следующий метод: https://github.com/ReactiveX/RxJS/blob/master/src%2FSubscriber.ts#L188
Разница в том, что первый метод повторно генерирует исключение в стеке вызовов, тогда как второй вместо этого распространяет ошибку на последующие подписки.
Почему оператор do распространяет ошибку вперед, а обработчик "next" возвращает ошибку обратно? Мне это кажется странным.