RxJS: как сгенерировать ошибку и отловить? - PullRequest
0 голосов
/ 09 ноября 2018

Это не связано с ошибкой, с которой я сталкиваюсь, а скорее с синтаксисом.

Рабочий процесс прост:

  • сделать HTTP-запрос, который возвращает логическое значение
  • если логическое значение истинно, тогда продолжить
  • если логическое значение равно false, записать предупреждение и остановить поток.

Чтобы управлять этим, мой текущий код выглядит так:

Boilerplate

private _getBoolean() { return this.http.get(...); }
private _getData() { return this.http.get(...); }

Текущий код

public getData() {
  return this._getBoolean().pipe(
    filter(bool => {
      if(!bool) {
        console.warn('Wrong server answer, stream stopped');
        return false;
      }
      return true;
    }),
    switchMap(bool => this._getData())
  );
}

И я не знаю почему, но это не кажется мне естественным и оптимизированным.

Я думал, что будет что-то, что упростит синтаксис, что-то вроде этого

public getData() {
  return this._getBoolean().pipe(
    throwError(bool => bool ? new Error('Wrong server answer, stream stopped') : null),
    catchError(err => console.warn(err)),
    switchMap(bool => this._getData())
  );
}

Есть ли что-то в этом роде или у меня правильный синтаксис?

Ответы [ 3 ]

0 голосов
/ 09 ноября 2018

Рассмотрим следующую наблюдаемую ниже, которая излучает значение от 1 до 4. Допустим, выдается ошибка, когда значение равно 3. Эта ошибка может быть поймана в операторе catchError или она может быть поймана в пределах subscribe. Я полагаю, что это зависит от конкретного варианта использования: позволите ли вы сообщать об ошибке пузырю вплоть до подписчика или ее нужно обработать где-то перед подписчиком.

of(1, 2, 3, 4).pipe(
  // Throw error when value is 3
  tap(value => { if(value === 3) throw new Error('Oops!') }),
  catchError(err => {
    console.log('Catch error in operator', err);

    // You can rethrow the same error or a new error
    // return throwError(err);

    // Or you can handle the error and return a new observable
    return of(3)
  })
).subscribe(
  value => console.log(value),
  // If `catchError` returns a new observable, then the error 
  // function here will not be called
  err => console.log('Catch error within subscribe', err),
  () => console.log('Done!')
)

Обратите внимание, что в этом примере, даже если ошибка обрабатывается, наблюдаемое завершается и значение 4 никогда не выдается. Если вы хотите сохранить наблюдаемую работоспособной при возникновении ошибки en, взгляните на этот ответ StackOverflow .

0 голосов
/ 09 ноября 2018

вместо:

public getData() {
  return this._getBoolean().pipe(
    throwError(bool => bool ? new Error('Wrong server answer, stream stopped') : null),
    catchError(err => console.warn(err)),
    switchMap(bool => this._getData())
  );
}

почему не что-то вроде:

public getData() {
  return this._getBoolean().pipe(
    tap(result => !result && throwError('Wrong server answer, stream stopped')),
    switchMap(bool => this._getData()),
    catchError(err => console.warn(err))
  );
}
0 голосов
/ 09 ноября 2018

Я не уверен, правильно ли я понял вашу проблему, но вы можете заменить

    console.warn('Wrong server answer, stream stopped');
    return false;

С

   Observable.throw('Some error cause')

А затем перехватите его с ближайшим блоком catch в вашем потоке, который дает вам в основном замену на: - Остановить поток, если вы повторно выбрасываете ошибку - Перезапустите его, если вы возвращаете входные данные наблюдаемые - вернуть совершенно новую наблюдаемую

public getData() {
  return this._getBoolean().pipe(
    filter(bool => {
      if(!bool) {
        console.warn('Wrong server answer, stream stopped');
        //return false;
        Observable.throw('I got false where I expected true')
      }
      return true;
    }),
    switchMap(bool => this._getData())
  );
}

А потом:

getData()
.any()
.operator()
.you()
.wish()
.catch(e => {
  /* Here stream will be terminated on thrown error */
})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...