rxjs5 merge and error handling

会有一股神秘感。 提交于 2019-12-05 10:32:42

I think you can simulate the same behavior by using catch(). You'll just need to append it to every source Observable:

const sources = [source1, source2, source3].map(obs => 
  obs.catch(() => Observable.empty())
);

Rx.Observable
  .merge(sources)
  .finally(...)
  ...

If you don't want to swallow your errors, but want to delay them to the end, you can:

const mergeDelayErrors = [];
const sources = [source1, source2, source3].map(obs => obs.catch((error) => {
  mergeDelayErrors.push(error);
  return Rx.Observable.empty();
}));

return Rx.Observable
  .merge(...sources)
  .toArray()
  .flatMap(allEmissions => {
    let spreadObs = Rx.Observable.of(...allEmissions);
    if (mergeDelayErrors.length) {
      spreadObs = spreadObs.concat(Rx.Observable.throw(mergeDelayErrors));
    }
    return spreadObs;
  })

You may want to throw only the first error, or create a CompositeError. I'm not sure how mergeDelayErrors originally behaved when multiple errors were thrown.

Unfortunately, because this implementation must wait until the all observables complete before emitting errors, it also waits until all observables complete before emitting next. This is likely not the original behavior of mergeDelayError, which is supposed to emit as a stream, rather than emitting them all at the end.

We can avoid blocking the stream by collecting the errors and emitting them at the end.

function mergeDelayError(...sources) {
  const errors = [];
  const catching = sources.map(obs => obs.catch(e => {
    errors.push(e);
    return Rx.Observable.empty();
  }));
  return Rx.Observable
    .merge(...catching)
    .concat(Rx.Observable.defer(
      () => errors.length === 0 ? Rx.Observable.empty() : Rx.Observable.throw(errors)));
}


const source1 = Rx.Observable.of(1,2,3);
const source2 = Rx.Observable.throw(new Error('woops'));
const source3 = Rx.Observable.of(4,5,6);

mergeDelayError(source1, source2, source3).subscribe(
  x => console.log('next:', x),
  e => console.log('error:', e),
  () => console.log('completed'));
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!