Почему Rxjs отписывается об ошибке в обратном вызове подписки? - PullRequest
1 голос
/ 20 марта 2019

Я использую RxJS 5.2.0 (да, он довольно старый). Я подписываюсь на некоторые наблюдаемые и хочу выполнить некоторый код. Если в этом коде есть ошибка js, то RxJS просто отписает моего подписчика и не сообщит об ошибке в консоль.

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

Единственный способ, которым я вижу, - это обернуть весь код моих подписчиков в try-catch. Но выглядит безумно, таких мест сотни.

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

Вот пример на jsfiddle https://jsfiddle.net/Eugene_Ilyin/18kw3hde/

let subj = new Rx.BehaviorSubject(1);

subj.asObservable().subscribe(number => {
  console.log(number);
  let book;
  book.page();
  console.log(number);
});

setTimeout(() => {
  subj.next(2);
}, 1000);

Есть строка book.page();, которая вызывает ошибку. Но в консоли браузера вы не увидите никакой ошибки. После ошибки подписка больше не будет вызываться. Потому что он будет отписан RxJS, когда он поймает ошибку по этому коду:

SafeSubscriber.prototype.__tryOrSetError = function (parent, fn, value) {
    try {
        fn.call(this._context, value);
    }
    catch (err) {
        parent.syncErrorValue = err;
        parent.syncErrorThrown = true;
        return true;
    }
    return false;
};

Этот вопрос может быть связан с моим вопросом. Но ситуация несколько иная и не дает ответа.

1 Ответ

1 голос
/ 20 марта 2019

попробуйте это.Вы должны ставить логику в операторах, а не внутри подписываться.Посмотрите на этот вопрос rxjs.Это хорошая практика, чтобы иметь код в методе подписки?

let subj = new Rx.BehaviorSubject(1);

subj.asObservable().do(()=>{
  console.log(number);
  let book;
  book.page();
  console.log(number);
}).catch(e => {
  console.error(e);
  return Rx.Observable.throw(e)
}).onErrorResumeNext()
  .subscribe(number => {
});

setTimeout(() => {
  subj.next(2);
}, 1000);

catch оператор поймает вас на ошибку и onErrorResumeNext() сохранит подписку.

https://jsfiddle.net/cvd7Lu4q/

...