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

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

原文由 user233232 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 343
2 个回答

当我开始看 Rxjs 时,我也偶然发现了那块石头。对我有帮助的是以下内容:

  • 来自 reactx.io 的文档。例如,对于 flatMaphttp ://reactivex.io/documentation/operators/flatmap.html
  • 来自 rxmarbles 的文档: http: //rxmarbles.com/。你不会在那里找到 flatMap ,你必须看看 mergeMap 而不是(另一个名字)。
  • 您遗漏的 Rx 介绍: https ://gist.github.com/staltz/868e7e9bc2a7b8c1f754。它解决了一个非常相似的例子。特别是,它解决了这样一个事实,即 promise 类似于仅发出一个值的 observable。
  • 最后查看来自 RxJava 的类型信息。未输入 Javascript 在这里无济于事。 Basically if Observable<T> an observable object which pushes values of type T, then flatMap takes a function of type T' -> Observable<T> as its argument, and returns Observable<T>map 采用类型为 T' -> T 的函数并返回 Observable<T>

回到您的示例,您有一个从 url 字符串生成承诺的函数。所以 T' : stringT : promise 。根据我们之前所说的 promise : Observable<T''> ,所以 T : Observable<T''>T'' : html 。 If you put that promise producing function in map , you get Observable<Observable<T''>> when what you want is Observable<T''> : you want the observable to emit the html 价值观。 flatMap 之所以这样称呼是因为它展平了(删除了一个可观察层)来自 map 的结果。根据你的背景,这对你来说可能是中文,但通过输入信息和从这里绘图,一切对我来说都变得非常清晰: http ://reactivex.io/documentation/operators/flatmap.html。

原文由 user3743222 发布,翻译遵循 CC BY-SA 4.0 许可协议

['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。

如果你有一个由另一个可观察对象产生的可观察对象,你不能直接过滤、减少或映射它,因为你有一个可观察对象而不是数据。如果您生成一个可观察对象,请选择 flatMap over map;那你就没事了。

与第二个片段一样,如果您正在进行异步操作,则需要使用 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>

原文由 serkan 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题