[angular]RxJSを使用して複数のHttp要求を処理する
6494 ワード
あるページにアクセスすると、複数のAPIアドレスからデータを取得して表示する必要がある場合があります.複数の非同期データ要求を管理することは困難ですが、Angular HttpサービスとRxJSライブラリが提供する機能を利用して上記の機能を実現できます.複数のリクエストを処理するには、シリアルまたはパラレルを使用する方法がいくつかあります.
基礎知識
mergeMap
mergeMapオペレータは、内部のObservableオブジェクトから値を取得し、親ストリームオブジェクトに返すために使用します. Observableオブジェクト(jsBin) をマージ
上記の例では、2つのObservableタイプが含まれています.ソースObservableオブジェクト-すなわちsourceオブジェクト 内部Observableオブジェクト-すなわちRx.Observable.of( 内部のObservableオブジェクトから値が発行された場合にのみ、ソースObservableオブジェクトから出力された値がマージされ、マージされた値が最終的に出力されます.
forkJoin
forkJoinはRxバージョンです複数のObservableオブジェクト(jsBin) をマージ
Httpリクエストの処理
まず、Angular Httpサービスの簡単な例を見てみましょう.
上記の例では、注入に依存する方法で注入します.
サービス、そして
メソッドでhttpオブジェクトを呼び出す
メソッドを使用してデータを取得します.この例は簡単で、1つのリクエストのみを処理します.次に、2つのリクエストをどのように処理するかを見てみましょう.
MapとSubscribe
次のリクエストを送信する場合、前のリクエストのデータに依存する必要がある場合があります.すなわち、前の要求のコールバック関数で対応するデータを取得し、別のHTTP要求を開始する必要がある.
上記の例では、まず
アドレスはすべてのユーザーの情報を取得し、指定したユーザーの
ユーザーの詳細をさらに取得します.機能は実現しましたが、より良い解決策はありますか?答えはありますが、RxJSライブラリで提供できます
オペレータは、上記のプロセスを最適化します.
mergeMap
上記の例では
オペレータは、ネストされたサブスクリプションの問題を解決します.最後に、複数の並列Httpリクエストをどのように処理するかを見てみましょう.
forkJoin
次の例では、
オペレータ.Promisesに詳しい方は、このオペレータと
実装される機能は似ています.
オペレータは、Observableオブジェクトのリストを受信し、並列に実行します.リストのObservableオブジェクトが値を発行すると、
話があるんだ
mergeMap以外に、RxJSのswitchMapは何の役に立ちますか?
switchMapオペレータは、ソースObservableオブジェクトから発行される値をマッピング処理するために使用されます.新しいObservableオブジェクトが表示されると、新しいObservableオブジェクトが新しい値を発行した後、前の未処理のObservableオブジェクトがキャンセルされます.
使用例:JSBin
例marble図:
以上のコードが実行された後、コンソールの出力結果:
実際にHttpサービスを利用するシーンでは、AutoComplete機能を実現するなど、
オペレータは、不要なHttpリクエストをキャンセルします.
基礎知識
mergeMap
mergeMapオペレータは、内部のObservableオブジェクトから値を取得し、親ストリームオブジェクトに返すために使用します.
const source = Rx.Observable.of('Hello');
//map to inner observable and flatten
const example = source.mergeMap(val => Rx.Observable.of(`${val} World!`));
const subscribe = example.subscribe(val => console.log(val)); //output: 'Hello World!'
上記の例では、2つのObservableタイプが含まれています.
${val} World!
)オブジェクトforkJoin
forkJoinはRxバージョンです
Promise.all()
、すなわち、すべてのObservableが完了するまで、値が一度に返されないことを示す.const getPostOne$ = Rx.Observable.timer(1000).mapTo({id: 1});
const getPostTwo$ = Rx.Observable.timer(2000).mapTo({id: 2});
Rx.Observable.forkJoin(getPostOne$, getPostTwo$).subscribe(
res => console.log(res) // [{id: 1}, {id: 2}]
);
Httpリクエストの処理
まず、Angular Httpサービスの簡単な例を見てみましょう.
import { Component, OnInit } from '@angular/core';
import { Http } from '@angular/http';
import 'rxjs/add/operator/map';
@Component({
selector: 'app-root',
template: `
HttpModule Demo
`
})
export class AppComponent implements OnInit {
constructor(private http: Http) { }
ngOnInit() {
this.http.get('https://jsonplaceholder.typicode.com/users')
.map(res => res.json())
.subscribe(users => console.log(users));
}
}
上記の例では、注入に依存する方法で注入します.
http
サービス、そして
ngOnInit()
メソッドでhttpオブジェクトを呼び出す
get()
メソッドを使用してデータを取得します.この例は簡単で、1つのリクエストのみを処理します.次に、2つのリクエストをどのように処理するかを見てみましょう.
MapとSubscribe
次のリクエストを送信する場合、前のリクエストのデータに依存する必要がある場合があります.すなわち、前の要求のコールバック関数で対応するデータを取得し、別のHTTP要求を開始する必要がある.
import { Component, OnInit } from '@angular/core';
import { Http } from '@angular/http';
import 'rxjs/add/operator/map';
@Component({
selector: 'app-root',
template: `
{{username}} Detail Info
{{user | json}}
`
})
export class AppComponent implements OnInit {
constructor(private http: Http) { }
apiUrl = 'https://jsonplaceholder.typicode.com/users';
username: string = '';
user: any;
ngOnInit() {
this.http.get(this.apiUrl)
.map(res => res.json())
.subscribe(users => {
let username = users[6].username;
this.http.get(`${this.apiUrl}?username=${username}`)
.map(res => res.json())
.subscribe(
user => {
this.username = username;
this.user = user;
});
});
}
}
上記の例では、まず
https://jsonplaceholder.typicode.com/users
アドレスはすべてのユーザーの情報を取得し、指定したユーザーの
username
ユーザーの詳細をさらに取得します.機能は実現しましたが、より良い解決策はありますか?答えはありますが、RxJSライブラリで提供できます
mergeMap
オペレータは、上記のプロセスを最適化します.
mergeMap
import { Component, OnInit } from '@angular/core';
import { Http } from '@angular/http';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/mergeMap';
@Component({
selector: 'app-root',
template: `
{{username}} Detail Info
{{user | json}}
`
})
export class AppComponent implements OnInit {
constructor(private http: Http) { }
apiUrl = 'https://jsonplaceholder.typicode.com/users';
username: string = '';
user: any;
ngOnInit() {
this.http.get(this.apiUrl)
.map(res => res.json())
.mergeMap(users => {
this.username = users[6].username;
return this.http.get(`${this.apiUrl}?username=${this.username}`)
.map(res => res.json())
})
.subscribe(user => this.user = user);
}
}
上記の例では
mergeMap
オペレータは、ネストされたサブスクリプションの問題を解決します.最後に、複数の並列Httpリクエストをどのように処理するかを見てみましょう.
forkJoin
次の例では、
forkJoin
オペレータ.Promisesに詳しい方は、このオペレータと
Promise.all()
実装される機能は似ています.
forkJoin
オペレータは、Observableオブジェクトのリストを受信し、並列に実行します.リストのObservableオブジェクトが値を発行すると、
forkJoin
オペレータが返すObservableオブジェクトは、新しい値、すなわち、すべてのObservableオブジェクトの出力値を含むリストを発行します.具体例は次のとおりです.import { Component, OnInit } from '@angular/core';
import { Http } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/observable/forkJoin';
@Component({
selector: 'app-root',
template: `
Post Detail Info
- {{post1 | json}}
- {{post2 | json}}
`
})
export class AppComponent implements OnInit {
constructor(private http: Http) { }
apiUrl = 'https://jsonplaceholder.typicode.com/posts';
post1: any;
post2: any;
ngOnInit() {
let post1 = this.http.get(`${this.apiUrl}/1`);
let post2 = this.http.get(`${this.apiUrl}/2`);
Observable.forkJoin([post1, post2])
.subscribe(results => {
this.post1 = results[0];
this.post2 = results[1];
});
}
}
話があるんだ
mergeMap以外に、RxJSのswitchMapは何の役に立ちますか?
switchMapオペレータは、ソースObservableオブジェクトから発行される値をマッピング処理するために使用されます.新しいObservableオブジェクトが表示されると、新しいObservableオブジェクトが新しい値を発行した後、前の未処理のObservableオブジェクトがキャンセルされます.
使用例:JSBin
var source = Rx.Observable.fromEvent(document.body, 'click');
var example = source.switchMap(e => Rx.Observable.interval(100).take(3));
example.subscribe({
next: (value) => { console.log(value); },
error: (err) => { console.log('Error: ' + err); },
complete: () => { console.log('complete'); }
});
例marble図:
source : -----------c--c-----------------...
concatMap(c => Rx.Observable.interval(100).take(3))
example: -------------0--0-1-2-----------...
以上のコードが実行された後、コンソールの出力結果:
0
0
1
2
実際にHttpサービスを利用するシーンでは、AutoComplete機能を実現するなど、
switchMap
オペレータは、不要なHttpリクエストをキャンセルします.