While your expected behavior cannot be achieved due to the Observable (OnNext)* (OnCompleted|OnError) , there are practical ways to work around this correctly by introducing hot observation.
let hotRange = Rx.Observable.range(1,3).publish(); let safeRange = hotRange .map(function (i) { if (i === 2) { throw "Error"; } else { return i; } }) .retry(); safeRange.subscribe(i => console.log(i)); hotRange.connect();
See JSBin . range Observable that you mentioned in the question is cold Observed. It behaves like a movie , so if an error occurs and we re-subscribed, we need to subscribe from the very beginning of the “movie”, that is 1 , then "Error" .
You probably had the implied assumption that Rx.Observable.range(1, 3) is a living observable, i.e. "hot". Since this is not the case, I did hotRange above using publish() . Thus, he will generate his events regardless of his subscribers. If we want to "continue" after an error, we need our source ("hotRange") without errors. This is why range.map( ) not a hot Observable. retry() will catch errors on hotRange.map( ) and replace it with hotRange.map( ) . Since hotRange is hot, each retry() execution will be different because it does not remember previous values coming from hotRange . Therefore, when the error caused by 2 is replaced with hotRange.map( ) in repeat, hotRange will subsequently emit 3 and pass the map function without errors.
source share