Angular 捕获异常

要捕获拒绝,我们使用订阅者的 errorcomplete的回调。

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 }`)
        );
      });
  }
}

View Example

它还允许我们检查错误并决定采取哪条路由。例如,如果我们遇到服务器错误,则使用缓存版本的请求,否则重新抛出。

@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();
    }
}

View Example

重试

有时你可能想要重试失败的请求。例如,如果用户离线,你可能需要每隔一段时间或不停地重试。

使用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);
  }
}