欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解使用angular的HttpClient搭配rxjs

 更新時(shí)間:2017年09月01日 08:19:25   作者:http://www.cnblogs.com/yitim/p/7458576.html  
本篇文章主要介紹了詳解使用angular的HttpClient搭配rxjs ,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧

一、原Http使用總結(jié)

使用方法

1.在根模塊或核心模塊引入HttpModule

即在AppModule或CoreModule中引入HttpModule:

import { HttpModule } from '@angular/http';
@NgModule({
 import: [ HttpModule ]
 // ...
})
AppModule {}

2.在使用的地方注入Http服務(wù)

import { Http } from '@angular/http';
// ...
constructor(
 private http: Http
) {}
ngOnInit() {
 this.http.get(`url`).subscribe((res) => {
// 成功回調(diào)
 }, (err) => {
// 失敗回調(diào)
 });
}
// ...

3.使用可選參數(shù)

 若想在請(qǐng)求中添加特定的頭部或者身體,就需要配置請(qǐng)求的可選參數(shù):

import { Http, Header } from '@angular/http';
// ...
this.http.delete(`url`, {headers: new Header(), body: { } }).subscribe(...);
// ...

缺陷

已知缺陷之一為不支持文件傳輸,如果想要寫一個(gè)文件上傳的客戶端,就只能使用JS原生的XMLHttpRequest對(duì)象,然后自己封裝上rxjs得到一個(gè)較通用的文件上傳服務(wù),可以參考 ngx-uploader。

另一個(gè)不能算缺陷的缺陷是Http請(qǐng)求得到的響應(yīng)結(jié)果必須手動(dòng)執(zhí)行json()以得到j(luò)son格式的結(jié)果。

二、改用HttpClient

HttpClient能力在angular 4.3版本開始引入在@angular/common/http中

使用方法

基本使用方法與原Http服務(wù)類似,先引入HttpClientModule,然后注入HttpClient服務(wù)使用:

import { HttpClientModule } from '@angular/common/http';
// ...
@NgModule({
 import: [ HttpClientModule ]
})
// ...
import { HttpClient } from '@angular/common/http';
// ...
constructor(
 private http: HttpClient
) {}
// ...
this.http.get('url').subscribe((res) => {
 // 成功回調(diào)
}, (err) => {
 // 失敗回調(diào)
});
// ...

添加額外頭部等信息的話類似原Http服務(wù),引入相關(guān)的變量后填入第二個(gè)可選參數(shù)即可。

改進(jìn)與加強(qiáng)

1.支持更多類型的請(qǐng)求,比如更改可選參數(shù)的responseType值可改為直接請(qǐng)求text內(nèi)容
2.不再需要手動(dòng)調(diào)用json()來將結(jié)果轉(zhuǎn)為json格式,訂閱到的結(jié)果已經(jīng)是body且轉(zhuǎn)為了json(請(qǐng)求text的話直接就是text內(nèi)容)。
3.支持監(jiān)聽請(qǐng)求進(jìn)度(可用于文件上傳)。
4.添加了攔截器能力,用于預(yù)設(shè)請(qǐng)求規(guī)則和響應(yīng)預(yù)處理。

缺陷

已知的一個(gè)小缺陷是,delete請(qǐng)求不能再添加body作為可選參數(shù)了,這個(gè)略尷尬,難道批量刪除也得乖乖把參數(shù)拼到url中。。。

三、攔截器

本文暫不討論文件上傳以及請(qǐng)求進(jìn)度的監(jiān)聽能力,可以查看官網(wǎng)的相關(guān)內(nèi)容,本文主要來講攔截器的簡(jiǎn)單使用。

給應(yīng)用注入攔截器的效果是,所有的HttpClient發(fā)起的請(qǐng)求都將執(zhí)行這個(gè)攔截器,類似Node中的中間件。且無論是請(qǐng)求之前的預(yù)處理還是得到響應(yīng)后的預(yù)處理都能做到。

筆者想到的第一個(gè)用處就是不再需要寫一個(gè)自己的Http服務(wù)來代執(zhí)行angular的Http服務(wù)了,以往如果想要給應(yīng)用的所有請(qǐng)求都添加比如認(rèn)證功能的請(qǐng)求頭的話,比較好的辦法就是自己建立一個(gè)MyHttp服務(wù)來代為調(diào)用Http方法,并在請(qǐng)求回調(diào)中添加統(tǒng)一的結(jié)果處理。

攔截器屬于特殊服務(wù),實(shí)現(xiàn)了HttpInterceptor類:

import {Injectable} from '@angular/core';
import {HttpEvent, HttpInterceptor, HttpHandler, HttpRequest} from '@angular/common/http';

@Injectable()
export class MyInterceptor implements HttpInterceptor {
 intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
 return next.handle(req);
 }
}

編輯好攔截器后需要注入到根模塊中:

import {NgModule} from '@angular/core';
import {HTTP_INTERCEPTORS} from '@angular/common/http';

@NgModule({
 providers: [{
 provide: HTTP_INTERCEPTORS,
 useClass: MyInterceptor,
 multi: true,
 }],
})
export class AppModule {}

預(yù)處理請(qǐng)求

所有工作都在攔截器中的intercept方法中進(jìn)行,如果要給所有請(qǐng)求加一個(gè)認(rèn)證頭部,可以操作其中的req參數(shù),注意req參數(shù)為只讀的,必須執(zhí)行其clone方法得到副本來操作,處理完的副本通過next參數(shù)發(fā)射出去即可:

public intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
 let authInfo = {token: 'testtoken', admin: 'testadmin'};
 const authReq = req.clone({
  headers: req.headers
  .set('Authorization', authInfo.token || '')
  .set('Admin', authInfo.admin || '')
  .set('Content-Type', 'application/json;charset=UTF-8')
 });
 return next.handle(authReq);
}

這樣實(shí)際使用請(qǐng)求時(shí)可以直接使用HttpClient,所有請(qǐng)求都會(huì)實(shí)現(xiàn)添加配置好的頭部信息。

響應(yīng)預(yù)處理

請(qǐng)求得到結(jié)果后,往往需要對(duì)結(jié)果進(jìn)行一些判斷,比如某些錯(cuò)誤是請(qǐng)求本身的錯(cuò)誤,這些錯(cuò)誤會(huì)直接拋出到rxjs的error流中,某些請(qǐng)求本身是成功的,但是是屬于一些服務(wù)器邏輯給出的錯(cuò)誤,這類錯(cuò)誤如果不做處理是會(huì)被認(rèn)為是成功的請(qǐng)求而直接next到成功回調(diào)的,這會(huì)導(dǎo)致最終訂閱請(qǐng)求時(shí),錯(cuò)誤的回調(diào)要做錯(cuò)誤處理,成功回調(diào)中也存在需要做錯(cuò)誤處理,感覺成功還得分為成功地成功和成功地失敗,很尷尬:

someReq().subscribe((res) => {
 if (res.state) {
 // 真正成功
 } else {
 // 還是失敗
 }
}, (err) => {
 // 失敗
});

通過攔截器可以對(duì)請(qǐng)求結(jié)果進(jìn)行重新整理,保證成功回調(diào)必然成功,失敗回調(diào)必然失?。?br />

return next.handle(authReq).map((event) => {
 if (event instanceof HttpResponse) {
 switch (event.status) {
  case 200:
  if (event.body['state']) {
  let newEvent = event.clone({body: event.body['data']});
  return newEvent;
  } else {
  throw event.body['msg'];
  }
  case 401:
  this.storage.remove('auth_token');
  this.router.navigate(['/login']);
  default:
  throw `【${event.status}】【${event.statusText}】`;
 }
 }
 return event;
});

響應(yīng)預(yù)處理的一句話總結(jié)就是操作intercept方法返回的next.handle(req),使用rxjs的map操作符進(jìn)行映射。

四、搭配rxjs

rxjs是angular嚴(yán)重依賴的一個(gè)大坑,初次接觸會(huì)被其創(chuàng)建和訂閱這種使用方式搭配一大堆眼花繚亂的操作符弄得一臉懵逼。

創(chuàng)建-訂閱的請(qǐng)求方式

原Http和新的HttpClient兩個(gè)服務(wù)流嚴(yán)重依賴了rxjs,請(qǐng)求的發(fā)起返回的是一個(gè)Observable對(duì)象,其定義好后并不會(huì)直接發(fā)起請(qǐng)求,真正發(fā)起請(qǐng)求是在執(zhí)行其subscribe方法的時(shí)候,此方法接收三個(gè)參數(shù),分別是成功回調(diào)、失敗回調(diào)和完成回調(diào)。

Promise的套路是請(qǐng)求在定義(調(diào)用)的時(shí)候就發(fā)起了,然后迎來的是一連串的then()和catch()??梢詮腸atch中resolve到then,或者從then中reject到catch。

rxjs的套路則是先創(chuàng)建出一個(gè)觀察者對(duì)象(Observable),可以用許多操作符定義許多規(guī)則,比如個(gè)人感覺很接近then的map操作符,以及接近c(diǎn)atch的catch操作符??梢詮膍ap操作符中直接throw到錯(cuò)誤回調(diào),或者在catch操作符中捕捉錯(cuò)誤并返回新的成功的流。這一切都不會(huì)觸發(fā)這個(gè)請(qǐng)求,只有最終subscribe()的時(shí)候,才會(huì)真正執(zhí)行整個(gè)請(qǐng)求,并在三種回調(diào)中體現(xiàn)。

對(duì)于rxjs的學(xué)習(xí)強(qiáng)烈推薦 Rxjs 5 ultimate 簡(jiǎn)直勝看十篇博。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論