要捕获拒绝,我们使用订阅者的 error
和 complete
的回调。
import { HttpClient } from "@angular/common/http";
import { Injectable } from '@angular/core';
@Injectable()
export class AuthService {
constructor(private http: HttpClient) {}
login(username, password) {
const payload = {
username: username,
password: password
};
this.http.post(`${ BASE_URL }/auth/login`, payload)
.catch( error => {
console.error("error catched", error);
return Observable.of({description: "Error Value Emitted"});
})
.subscribe(
authData => this.storeToken(authData.id_token),
(err) => console.error(err),
() => console.log('Authentication Complete')
);
}
}
捕获和释放
我们还可以选择使用.catch
运算符。它允许我们捕获现有流上的错误,做一些事情然后传递异常。
import { HttpClient } from "@angular/common/http";
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Rx';
@Injectable()
export class SearchService {
constructor(private http: HttpClient) {}
search(term: string) {
return this.http.get('https://api.spotify.com/v1/dsds?q=' + term + '&type=artist')
.catch((e) => {
return Observable.throw(
new Error(`${ e.status } ${ e.statusText }`)
);
});
}
}
它还允许我们检查错误并决定采取哪条路由。例如,如果我们遇到服务器错误,则使用缓存版本的请求,否则重新抛出。
@Injectable()
export class SearchService {
...
search(term: string) {
return this.http.get('https://api.spotify.com/v1/dsds?q=' + term + '&type=artist')
.map((response) => response.json())
.catch((e) => {
if (e.status >== 500) {
return cachedVersion();
} else {
return Observable.throw(
new Error(`${ e.status } ${ e.statusText }`)
);
}
});
}
}
取消请求
取消HTTP请求是常见的要求。 例如,您可以有一个请求队列,其中一个新请求取代一个待处理请求,并且该待处理请求需要取消。
要取消请求,我们称其订阅的unsubscribe
函数。
@Component({ /* ... */ })
export class MyApp {
/* ... */
search() {
const request = this.searchService.search(this.searchField.value)
.subscribe(
(result) => { this.result = result.artists.items; },
(err) => { this.errorMessage = err.message; },
() => { console.log('Completed'); }
);
request.unsubscribe();
}
}
重试
有时你可能想要重试失败的请求。例如,如果用户离线,你可能需要每隔一段时间或不停地重试。
使用RxJS retry
操作符。 它接受一个retryCount
参数。 如果没有返回结果,它将无限期重试序列。
请注意,在重试阶段不会调用错误回调。 如果请求失败,它将被重试,并且只有在所有重试尝试失败之后,流才会抛出错误。
import { HttpClient } from "@angular/common/http";
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Rx';
@Injectable()
export class SearchService {
constructor(private http: HttpClient) {}
search(term: string) {
let tryCount = 0;
return this.http.get('https://api.spotify.com/v1/dsds?q=' + term + '&type=artist')
.map((response) => response.json())
.retry(3);
}
}