2

我有一些代码正在迁移到 RxJS 5.5,它已经工作了。

public getMentor(id: number): Observable<Employee> {
    const url = `${this.employeeUrl}/${id}/mentor`;
    return this.http
        .get(url, this.authService.getOptionsWithToken())
        .retryWhen(errors => {
            return errors
                .mergeMap(error => (error.status === 404) ? Observable.throw(error) : Observable.of(error))
                .take(this.maxRetries);
        })
        .map(response => response.json() as Employee)
        .catch(ErrorHandlerService.handleError);
}

无论如何,如果这个请求失败并返回 404,按照业务逻辑是可以的。现在,这在 5.5 中几乎是等效的:

public getMentor(id: number): Observable<Employee> {
  const url = `${this.employeeUrl}/${id}/mentor`;
  return this.http.get<Employee>(url)
    .pipe(
      retryWhen(errors => {
        console.log('errorInService', errors);
        return errors.pipe(
          mergeMap(error => (error.status === 404) ? _throw(error) : of(error)),
          take(this.maxRetries)
        )
      }),
      catchError(ErrorHandlerService.handleError)
    );
}

在这里,流程被中断,因为在 retryWhen 中,errors 现在是一个主题,我无法像以前一样提取状态。

this.employeeService.getMentor(this.mentee.id).subscribe(
    mentor => {
      this.existingMentor = mentor;
      this.modalAddConfirmation(addConfirmation, mentee, form);
    },
    e => {
      console.log('errorInMentor', e);
      if (e.status === 404) {
        // console.log('No mentor');
        this.employeeService.putMentor(mentee.id, this.mentor)
          .subscribe(() => this.mentees.push(mentee));
      } else {
        return null;
      }
    }
  );

在最初的调用者中,“e”现在是一个字符串,Http failure response for http://localhost:8888/employees/1/mentor: 404 OK而不是一个对象。显然,putMentor()电话永远不会被打。我只是在学习,所以很可能我还没有完全理解新的可管道操作符。

更新

至少这段代码抛出了一个ErrorObservable,但在调用者端(errorInMentor)它仍然是一个字符串:

public getMentor(id: number): Observable<Employee> {
  const url = `${this.employeeUrl}/${id}/mentor`;
  return this.http.get<Employee>(url)
    .pipe(
      retryWhen(errors => {
        return errors.pipe(
          mergeMap(error => {
            console.log('error MergeMap', error);
            return error.status === 404 ? _throw(error) : of(error);
          }),
          take(this.maxRetries)
        )
      }),
      catchError(ErrorHandlerService.handleError)
    );
}
4

1 回答 1

1

原来,罪魁祸首是ErrorHandlerService.handleError()函数。以前它是这样工作的:

public static handleError(error: any): Promise<any> {
    console.error('An error occurred', error);
    return Promise.reject(error.message || error);
}

Promise 和 Pipeable 运算符相处得不好,所以我将代码更新为:

public static handleError(error: any): ErrorObservable {
    console.error('An error occurred', error);
    return ErrorObservable.create(error.message || error);
}

但是我只需要额外的调整:

public static handleError(error: any): ErrorObservable {
    console.error('An error occurred', error);
    return ErrorObservable.create(error);
}

直到现在我都不知道我是怎么错过的。

于 2018-03-01T20:36:42.027 回答