Javascript 为什么我们需要使用平面图?

Javascript 为什么我们需要使用平面图?,javascript,rxjs,Javascript,Rxjs,我开始使用RxJS,我不明白为什么在这个例子中我们需要使用像flatMap或concatAll这样的函数;这里的数组在哪里 var requestStream = Rx.Observable.just('https://api.github.com/users'); var responseMetastream = requestStream .flatMap(function(requestUrl) { return Rx.Observable.fromPromise(jQuer

我开始使用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)})

如果有人能直观地解释正在发生的事情,这将非常有帮助

它不是数组的数组。这是一个可观察的可观察的

下面返回一个可观察的字符串流

requestStream
  .map(function(requestUrl) {
    return requestUrl;
  });
而这将返回json的可观察流的可观察流

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

flatMap
为我们自动展平可观察对象,以便我们可以直接观察json流

当我开始查看
Rxjs
时,我也偶然发现了那块石头。帮助我的是:

  • 来自reactivex.io的文档。例如,对于
    flatMap
  • 来自rxmarbles的文档:。您不会在那里找到
    flatMap
    ,您必须查看
    mergeMap
    (另一个名称)
  • 您缺少的Rx简介:。它涉及一个非常类似的例子。特别是,它解决了这样一个事实,即承诺类似于只发出一个值的可观测值
  • 最后查看来自RxJava的类型信息。没有键入Javascript在这里没有帮助。基本上,如果
    Observable
    表示一个可观测对象,它推送类型为T的值,那么
    flatMap
    将类型为
    T'->Observable
    的函数作为其参数,并返回
    Observable
    map
    接受类型为
    T'->T
    的函数,并返回
    observatable

    回到您的示例,您有一个函数,它从url字符串生成承诺。所以
    T”:string
    ,和
    T:promise
    。根据我们之前所说的,
    promise:Observable
    ,因此
    T:Observable
    ,带有
    T':html
    。如果您将承诺生成函数放入
    map
    ,当您想要的是
    可观察的时候,您会得到
    可观察的
    :您想要可观察的发出
    html
    flatMap
    之所以这样调用,是因为它将
    map
    的结果展平(删除一个可观察的层)。根据你的背景,这对你来说可能是中文的,但在这里输入信息和绘图对我来说一切都变得非常清楚:


可观测对象是一个发出事件流的对象:下一个、错误和完成

当您的函数返回一个可观察的时,它不是返回一个流,而是一个可观察的实例。
flatMap
操作符只是将该实例映射到一个流

['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]]
这就是
flatMap
map
相比的行为:执行给定函数并将结果对象展平为流

['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]]
当你有一个结果更容易观察到的可观察对象时,你可以使用flatMap

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

和第二个代码片段一样,若要执行异步操作,则需要使用flatMap

var source=Rx.Observable.interval(100).take(10).map(函数(num){
返回num+1
});
来源.订阅(函数(e){
控制台日志(e)
})
带平面地图

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)})
没有平面图

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)})
})
简单:

[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
将一个可见光发射的项目转换为新的可见光,然后将这些项目的发射平坦化为单个可见光

查看下面的场景,其中
get(“posts”)
返回一个被
flatMap
压平的可观察对象

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将可观察对象发出的项目转换为 可观测到的,然后将这些排放物平坦化为单个 可观察

我发誓这个定义仍然让我感到困惑,但我将用最简单的方式解释它,就是用一个例子

我们的情况:我们有一个observable,它返回数据(简单URL),我们将使用该数据进行HTTP调用,该调用将返回一个包含我们所需数据的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);
          });
});
const mapFunction = p -> p.name;
const names = friends.map(mapFunction);
如您所见,我们无法直接获取所需的数据,因此检索数据的第一种方法是使用普通订阅,如下所示:

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);
          });
});
const mapFunction = p -> p.name;
const names = friends.map(mapFunction);
这是可行的,但正如您所看到的,我们必须嵌套订阅才能获取数据。目前看起来还不错,但假设我们有10个嵌套订阅,这些订阅将无法维护

因此,更好的处理方法是使用操作符
flatMap
,它将做同样的事情,但使我们避免嵌套订阅:

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

这里展示了使用subscribes的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;
    });

希望能有所帮助

奥利弗


flatMap将可见光发射的项目转换为可见光, 然后将这些气体的排放量展平为一个可观测值

我并不笨,但我读了10遍,还是不明白。当我阅读代码片段时:

[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]
然后我就能明白发生了什么,它做了两件事:

平面地图

  • 映射:将*)发射的项目转换为可见项
  • 展开:然后将这些观察值合并为一个观察值
  • *)“转换”一词表示该项可以转换为其他内容

    然后,合并操作符变得清晰,它在没有映射的情况下执行展平。为什么不把它称为“合并地图”?似乎还有一个别名mergeMap,其名称为flatMap

    flatMap用于将数组展平为s
    ["Max", "Jack", "Sam", "Alex", "Megan", "Mason", "Cameron", "Kaylin"]