处理 RxJS 5.5 中的 retryWhen 状态码
Handling retryWhen status code in RxJS 5.5
我有一些代码正在迁移到 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 中,错误现在是一个主题,我无法像以前那样提取状态。
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)
);
}
原来罪魁祸首是ErrorHandlerService.handleError()
函数。以前它是这样工作的:
public static handleError(error: any): Promise<any> {
console.error('An error occurred', error);
return Promise.reject(error.message || error);
}
Promises 和 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);
}
直到现在我都不知道我是怎么错过的。
我有一些代码正在迁移到 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 中,错误现在是一个主题,我无法像以前那样提取状态。
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)
);
}
原来罪魁祸首是ErrorHandlerService.handleError()
函数。以前它是这样工作的:
public static handleError(error: any): Promise<any> {
console.error('An error occurred', error);
return Promise.reject(error.message || error);
}
Promises 和 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);
}
直到现在我都不知道我是怎么错过的。