为什么 switchmap return 是一个 http 响应,而 map returns 是一个可观察的
Why does switchmap return a http response but map returns an observable
在这个例子中,switchMap 给出了 http 响应,但是当使用 map 时返回一个 Observable。我相信这与 'flattening' switchMap 确实有关,但仍然不明白 switchMap 在幕后做了什么来产生 http 响应结果。
import{Component, OnInit} from '@angular/core';
import {HttpClient} from '@angular/common/http';
import { of, from, Observable, forkJoin } from 'rxjs';
import { map, mergeMap, switchMap, tap, flatMap} from 'rxjs/operators';
@Component({
selector: 'star-wars',
template: ``,
})
export class StarWars {
private peopleUrl = 'https://swapi.co/api/people/';
constructor(private http: HttpClient) {}
ngOnInit() {
of(1)
.pipe(
map(() => this.http.get('https://swapi.co/api/people/1')),
// produces Observable {_isScalar: false, source: {…}
switchMap(() => this.http.get('https://swapi.co/api/people/1')),
// produces http response {name: "Luke Skywalker", height: "172", mass: "77", hair_color: "blond"…}
)
.subscribe(res => {
console.log(res)
})
}
}
任何关于 switchMap 在这里做什么来产生这种不同结果的澄清都将不胜感激。
Observables 中的 'flattening' 与您可能已经熟悉的展平数组的概念类似。
例如:
[[0], [1, 2], [3]].flatten()
// output [0, 1, 2, 3]
一般来说,扁平化意味着获取值类型的类型(例如值数组的数组)并返回值类型的值(例如值数组)。
Type of Types 有时会调用 higher-order Type(例如,higher-order function 是一个函数返回函数,higher-order Observable 是 Observable of Observables)。所以扁平化会将高阶类型转换为一阶类型。
用 TypeScript 编写 flatten
是一个具有以下签名的函数:
flatten(source: Type<Type<Value>>): Type<Value>
在 RxJS 中等价于 flatten
是 mergeAll
operator:
of(of(0), of(1, 2), of(3)).pipe(mergeAll())
// produce Observable<number> -> [0, 1, 2, 3]
map
和 flatten
的组合通常称为 flatMap
虽然名称可能不同,但主要概念是相同 - 将映射和展平作为一个动作进行。
在数组上下文中而不是:
[0, 1, 2, 3].map(x => Array(x).fill(x)).flatten()
// [[], [1], [2, 2], [3, 3, 3]].flatten()
// output: [1, 2, 2, 3, 3, 3]
我们可以直接使用:
[0, 1, 2, 3].flatMap(x => Array(x).fill(x))
RxJS 有相当多的运算符作为 flatMap
:
mergeMap
- 正在同时展平 Observables,因此输入和输出值可能处于不同的顺序
concatMap
- 一次一个连续地展平 Observables,因此输入和输出值将采用相同的顺序
switchMap
- 扁平化 Observable 但仅提供最新值
一般来说,这些 flatMap
类型的运算符将简单地调用 subscribe
到从映射函数返回的 Observable,并为我们管理底层订阅。
在这个例子中,switchMap 给出了 http 响应,但是当使用 map 时返回一个 Observable。我相信这与 'flattening' switchMap 确实有关,但仍然不明白 switchMap 在幕后做了什么来产生 http 响应结果。
import{Component, OnInit} from '@angular/core';
import {HttpClient} from '@angular/common/http';
import { of, from, Observable, forkJoin } from 'rxjs';
import { map, mergeMap, switchMap, tap, flatMap} from 'rxjs/operators';
@Component({
selector: 'star-wars',
template: ``,
})
export class StarWars {
private peopleUrl = 'https://swapi.co/api/people/';
constructor(private http: HttpClient) {}
ngOnInit() {
of(1)
.pipe(
map(() => this.http.get('https://swapi.co/api/people/1')),
// produces Observable {_isScalar: false, source: {…}
switchMap(() => this.http.get('https://swapi.co/api/people/1')),
// produces http response {name: "Luke Skywalker", height: "172", mass: "77", hair_color: "blond"…}
)
.subscribe(res => {
console.log(res)
})
}
}
任何关于 switchMap 在这里做什么来产生这种不同结果的澄清都将不胜感激。
Observables 中的 'flattening' 与您可能已经熟悉的展平数组的概念类似。
例如:
[[0], [1, 2], [3]].flatten()
// output [0, 1, 2, 3]
一般来说,扁平化意味着获取值类型的类型(例如值数组的数组)并返回值类型的值(例如值数组)。
Type of Types 有时会调用 higher-order Type(例如,higher-order function 是一个函数返回函数,higher-order Observable 是 Observable of Observables)。所以扁平化会将高阶类型转换为一阶类型。
用 TypeScript 编写 flatten
是一个具有以下签名的函数:
flatten(source: Type<Type<Value>>): Type<Value>
在 RxJS 中等价于 flatten
是 mergeAll
operator:
of(of(0), of(1, 2), of(3)).pipe(mergeAll())
// produce Observable<number> -> [0, 1, 2, 3]
map
和 flatten
的组合通常称为 flatMap
虽然名称可能不同,但主要概念是相同 - 将映射和展平作为一个动作进行。
在数组上下文中而不是:
[0, 1, 2, 3].map(x => Array(x).fill(x)).flatten()
// [[], [1], [2, 2], [3, 3, 3]].flatten()
// output: [1, 2, 2, 3, 3, 3]
我们可以直接使用:
[0, 1, 2, 3].flatMap(x => Array(x).fill(x))
RxJS 有相当多的运算符作为 flatMap
:
mergeMap
- 正在同时展平 Observables,因此输入和输出值可能处于不同的顺序concatMap
- 一次一个连续地展平 Observables,因此输入和输出值将采用相同的顺序switchMap
- 扁平化 Observable 但仅提供最新值
一般来说,这些 flatMap
类型的运算符将简单地调用 subscribe
到从映射函数返回的 Observable,并为我们管理底层订阅。