web-dev-qa-db-ja.com

flatMapを使用する必要があるのはなぜですか?

RxJSを使用し始めていますが、この例でflatMapconcatAllのような関数を使用する必要がある理由がわかりません。ここの配列の配列はどこですか?

var requestStream = Rx.Observable.just('https://api.github.com/users');

var responseMetastream = requestStream
  .flatMap(function(requestUrl) {
    return Rx.Observable.fromPromise(jQuery.getJSON(requestUrl));
  });

responseMetastream.subscribe(url => {console.log(url)})

誰かが何が起こっているかを視覚的に説明できれば、非常に役立ちます。

74
user233232

Rxjsを見始めたとき、私もその石につまずいた。私を助けたのは次のとおりです:

  • reactx.ioのドキュメント。たとえば、flatMapの場合: http://reactivex.io/documentation/operators/flatmap.html
  • rxmarblesのドキュメント: http://rxmarbles.com/ 。そこにはflatMapが見つかりません。代わりにmergeMap(別の名前)を調べる必要があります。
  • 欠落しているRxの紹介: https://Gist.github.com/staltz/868e7e9bc2a7b8c1f754 。非常によく似た例に対処します。特に、1つの値のみを出力するオブザーバブルに似ているという事実に対処します。
  • 最後に、RxJavaの型情報を確認します。 Javascriptが入力されていない場合、ここでは役に立ちません。基本的にObservable<T>がT型の値をプッシュするオブザーバブルオブジェクトを示す場合、flatMapは引数としてT' -> Observable<T>型の関数を取り、Observable<T>を返します。 mapは、タイプT' -> Tの関数を取り、Observable<T>を返します。

    例に戻ると、URL文字列からプロミスを生成する関数があります。 T' : string、およびT : promiseです。そして、前にpromise : Observable<T''>で言ったことから、T : Observable<T''>を使用して、T'' : htmlを使用しました。そのプロミス生成関数をmapに配置すると、Observable<Observable<T''>>が必要なときにObservable<T''>を取得できます。オブザーバブルにhtml値を発行させたい場合。 flatMapは、mapからの結果を平坦化(観察可能なレイヤーを削除)するため、そのように呼び出されます。あなたの背景に応じて、これはあなたにとって中国語かもしれませんが、情報とここからの描画を入力することで、すべてが明確になりました: http://reactivex.io/documentation/operators/flatmap.html

63
user3743222
['a','b','c'].flatMap(function(e) {
    return [e, e+ 'x', e+ 'y',  e+ 'z'  ];
});
//['a', 'ax', 'ay', 'az', 'b', 'bx', 'by', 'bz', 'c', 'cx', 'cy', 'cz']


['a','b','c'].map(function(e) {
    return [e, e+ 'x', e+ 'y',  e+ 'z'  ];
});
//[Array[4], Array[4], Array[4]]

結果がより多くのObservableであるObservableがある場合、flatMapを使用します。

別のオブザーバブルによって生成されるオブザーバブルがある場合、データではなくオブザーバブルがあるため、フィルター、縮小、または直接マッピングすることはできません。オブザーバブルを作成する場合は、mapよりflatMapを選択します。あなたは大丈夫です.

2番目のスニペットのように、非同期操作を行う場合、flatMapを使用する必要があります。

var source = Rx.Observable.interval(100).take(10).map(function(num){
    return num+1
});
source.subscribe(function(e){
    console.log(e)
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.4.1/Rx.min.js"></script>
var source = Rx.Observable.interval(100).take(10).flatMap(function(num){
    return Rx.Observable.timer(100).map(() => num)
});
source.subscribe(function(e){
    console.log(e)
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.4.1/Rx.min.js"></script>
102
serkan

flatMapは、Observableによって放出されたアイテムを新しいObservableに変換し、それらからの放出を単一のObservableにフラット化します。

get("posts")が、flatMapによって「フラット化」されたObservableを返すシナリオを確認してください。

myObservable.map(e => get("posts")).subscribe(o => console.log(o));
// this would log Observable objects to console.  

myObservable.flatMap(e => get("posts")).subscribe(o => console.log(o));
// this would log posts to console.
21
eosimosu

配列の配列ではありません。オブザーバブルのオブザーバブルです。

以下は、観測可能な文字列のストリームを返します。

requestStream
  .map(function(requestUrl) {
    return requestUrl;
  });

これは、jsonの観測可能なストリームの観測可能なストリームを返しますが

requestStream
  .map(function(requestUrl) {
    return Rx.Observable.fromPromise(jQuery.getJSON(requestUrl));
  });

flatMapは、jsonストリームを直接監視できるように、observableを自動的にフラット化します

16
Lucius

人々は物事を複雑にする傾向がありますと言う定義を与えることで:

flatMapはObservableから放出されたアイテムをObservableに変換し、それらからの放出を単一のObservableにフラット化します

私はまだこの定義を混乱させると誓いますが、例を使用することで最も簡単な方法で説明します

Our Situation:必要なデータを含むobservableを返すHTTP呼び出しを行うために使用するデータ(単純なURL)を返すobservableがあるので、このような状況を視覚化できます:

Observable 1
    |_
       Make Http Call Using Observable 1 Data (returns Observable_2)
            |_
               The Data We Need

ご覧のとおり、必要なデータに直接アクセスできないため、データを取得する最初の方法は、次のような通常のサブスクリプションのみを使用することです。

Observable_1.subscribe((URL) => {
         Http.get(URL).subscribe((Data_We_Need) => {
                  console.log(Data_We_Need);
          });
});

これは機能しますが、ご覧のとおり、データを取得するためにサブスクリプションをネストする必要がありますが、これは現在悪くはありませんが、メンテナンス不能になるネストされたサブスクリプションが10個あると想像してください。

したがって、これを処理するより良い方法は、演算子flatMapを使用することです。これは同じことを行いますが、ネストされたサブスクリプションを回避します。

Observable_1
    .flatMap(URL => Http.get(URL))
    .subscribe(Data_We_Need => console.log(Data_We_Need));
15
Hamed Baatour

シンプル:

[1,2,3].map(x => [x, x * 10])
// [[1, 10], [2, 20], [3, 30]]

[1,2,3].flatMap(x => [x, x * 10])
// [1, 10, 2, 20, 3, 30]]
13
drpicox

Observableは、Next、Error、Completedのイベントのストリームを発行するオブジェクトです。

関数がObservableを返すとき、ストリームではなくObservableのインスタンスを返します。 flatMap演算子は、そのインスタンスをストリームに単純にマップします。

それがflatMapと比較したときのmapの動作です:指定された関数を実行し、結果のオブジェクトをストリームにフラット化します。

13
AkkarinZA

ここでは、サブスクライブを使用したflatMapの同等の実装を示します。

FlatMapなし:

this.searchField.valueChanges.debounceTime(400)
.subscribe(
  term => this.searchService.search(term)
  .subscribe( results => {
      console.log(results);  
      this.result = results;
    }
  );
);

FlatMapの場合:

this.searchField.valueChanges.debounceTime(400)
    .flatMap(term => this.searchService.search(term))
    .subscribe(results => {
      console.log(results);
      this.result = results;
    });

http://plnkr.co/edit/BHGmEcdS5eQGX703eRRE?p=preview

それが役立つことを願っています。

オリビエ。

7

FlatMapを使用

var requestStream = Rx.Observable.just('https://api.github.com/users');

var responseMetastream = requestStream
  .flatMap(function(requestUrl) {
    return Rx.Observable.fromPromise(jQuery.getJSON(requestUrl));
  });

responseMetastream.subscribe(json => {console.log(json)})

FlatMapなし

var requestStream = Rx.Observable.just('https://api.github.com/users');

var responseMetastream = requestStream
  .map(function(requestUrl) {
    return Rx.Observable.fromPromise(jQuery.getJSON(requestUrl));
  });

responseMetastream.subscribe(jsonStream => {
  jsonStream.subscribe(json => {console.log(json)})
})
5
Thanawat