为什么我们需要使用flatMap?
我开始使用RxJS,我不明白为什么在这个例子中我们需要使用像flatMap
或concatAll
这样的函数; 这里的数组数组在哪里?
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/。 你不会在那里find
flatMap
,你必须看看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' : string
,T : 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。
这是flatMap
与map
相比的行为:执行给定的函数并将生成的对象平铺到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)}) })