为什么我们需要使用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)}) 

如果有人可以直观地解释发生的事情,这将是非常有帮助的。

当我开始看Rxjs我也偶然发现了这块石头。 帮助我的是以下几点:

  • 来自reactivex.io的文档。 例如,对于flatMap : http: flatMap
  • 来自rxmarbles的文档: http: //rxmarbles.com/。 你不会在那里findflatMap ,你必须看看switchMap (另一个名字)。
  • Rx的介绍,你已经失踪了: https : //gist.github.com/staltz/868e7e9bc2a7b8c1f754 。 它解决了一个非常相似的例子。 特别是它处理了一个事实,即一个承诺类似于一个只能看到一个价值的可观察到的事物。
  • 最后看RxJava的types信息。 没有键入的Javascript在这里没有帮助。 基本上,如果Observable<T>表示一个可观察的对象,它推入Ttypes的值,那么flatMap接受一个types为T' -> Observable<T>的函数作为参数,并返回Observable<T>map采用typesT' -> T的函数并返回Observable<T>

    回到你的例子,你有一个函数可以从urlstring中产生promise。 所以T' : stringT : promise 。 根据我们之前所说的promise : Observable<T''> ,所以T : Observable<T''> ,用T'' : html 。 如果你把这个承诺放在map产生函数,当你想要的是Observable<T''>时,你得到Observable<Observable<T''>> :你希望observable发出html值。 flatMap就是这样调用的,因为它将map的结果弄平(移除一个可观察的图层)。 根据你的背景,这可能对你来说是中国的,但是从这里input信息和绘图,一切都变得清晰: http://reactivex.io/documentation/operators/flatmap.html : http://reactivex.io/documentation/operators/flatmap.html

 ['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结果更可观察的时候,你可以使用flatMap。

如果你有一个由另一个observable产生的observable,你不能过滤,缩小或者直接映射它,因为你有一个Observable而不是数据。 如果你生成一个可观察的selectflatMap over map; 那么你没事。

在第二个片段中,如果你正在做asynchronous操作,你需要使用flatMap。

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

这不是一个数组的数组。 这是可观察的(s)的可观察的。

以下内容返回一个可观察的stringstream。

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

虽然这返回一个可观察的jsonstream

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

flatMap自动为我们展平observable,所以我们可以直接观察jsonstream

Observable是一个发射事件stream的对象:Next,Error和Completed。

当你的函数返回一个Observable时,它不返回一个stream,而是一个Observable的实例。 flatMap操作符只是将该实例映射到一个stream。

这是flatMapmap相比的行为:执行给定的函数并将生成的对象平铺到stream中。

简单:

 [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]] 

flatMap将Observable发射的flatMap转化为新的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. 

与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)}) })