Привязка обратного вызова функции Angular 2 и RxJs к this заставляет HTTP-запрос повторяться снова и снова

У меня есть метод обработки наших ошибок из HTTP-запросов, и он выглядит так

public handleError(err: any, caught: Observable<any>): Observable<any> {

  //irrelevant code removed
  this.logger.debug(err);//example of problem 
  return caught;
}

Он вызывается так (пример метода, но показывает ошибку)

  public makeHttpCall() {
    this.http.get("http://api.exmaple.com/getsomedata")
      .map(r=> r.json())
      .catch(this.handleError);
  }

Проблема с приведенным выше кодом заключается в том, что при вызове this.logger.debug(err) в handleError методе this больше не обращается к классу, из которого был сделан вызов http, а ссылается на CatchSubscriber.

См. Здесь:  пример этого

Поэтому я меняю .catch(this.handleError); на .catch(this.handlError.bind(this));

Это работает, теперь, когда я вызываю this.logger.debug this, относится к правильному объекту. Проблема в том, что http-запрос вызывается снова и снова, см. Здесь:

введите описание изображения здесь

Это происходит только после применения .bind(this)

Я не могу понять, почему это происходит

*********РЕДАКТИРОВАТЬ*********

Изменение с .catch(handleError) на .catch((a,b)=>handleError(a,b)) исправляет ссылку на this, но HTTP-запрос снова и снова рассылается спамом, но только в случае сбоя запроса. Если запрос выполнен успешно, это происходит только один раз.


person Steven Yates    schedule 20.10.2016    source источник
comment
решает ли это вашу проблему? > stackoverflow.com/questions/36227996/?   -  person Harry Ninh    schedule 20.10.2016


Ответы (1)


Когда вы передаете функцию с .catch(this.handleError);, она теряет свой контекст this. См. Почему я теряю контекст этого в Javascript?

Проще всего это исправить, заключив вызов функции в закрытие.

.catch((err, caught) => this.handleError(err, caught));
person martin    schedule 20.10.2016
comment
Это исправляет ссылку this, но запрос по-прежнему повторяется снова и снова. - person Steven Yates; 20.10.2016
comment
Конечно, вы возвращаете исходный Observable, который выдал ошибку в handleError(), и оператор .catch() повторно подписывается на него. Это то, что catch() делает по замыслу github. com / Reactive-Extensions / RxJS / blob / master / doc / api / core / - person martin; 20.10.2016
comment
Спасибо @Martin, я не видел, что Продолжает наблюдаемую последовательность, которая завершается исключением со следующей наблюдаемой последовательностью. Так как же предотвратить его продолжение? Возврат null вызовет ошибку. - person Steven Yates; 20.10.2016
comment
@StevenYates Вы предотвращаете это, не используя оператор catch(), если вам не нужны его функции. Итак, вопрос в том, почему вы вообще используете catch(). Другой вариант - вернуть фиктивный Observable, например Observable.of(null). - person martin; 20.10.2016
comment
Я использую catch для регистрации ошибок. Возможно, я использую неправильный метод, но мне просто нужно регистрировать все, что идет не так с запросом. Должен ли я использовать другой метод? - person Steven Yates; 20.10.2016
comment
@StevenYates Тогда тебе вообще не следует использовать catch(). Вместо этого используйте метод subscribe() здесь reactivex.io/rxjs / class / es6 / или - person martin; 20.10.2016