我已经看过许多其他有关该主题的文章,并且阅读了https://www.learnrxjs.io/operators/transformation/switchmap.html之类的官方(见下文)和半官方文档,但是我仍然无法内化“地图”和“ switchMap”,并希望通过下面的具体示例进行说明。
根据RxJS官方文档的说明:
出于对我的不全面理解,我做了一些非常简单的示例,请参见StackBlitz https://stackblitz.com/edit/rxjs-xpicph?devtoolsheight=60,但仍然不完全理解为什么某些示例以它们的方式产生其输出的原因。
首先,提供一些非常简单的string
示例:
// String Example 1
const source = of('World').pipe(
map(x => `Hello ${x}!`)
);
source.subscribe(x => console.log(`SOURCE (map): ${x}`));
// SOURCE (map): Hello World!
好的,很公平,我想我主要是得到这个。
因此,我们得到输出:“ Hello World”
// String Example 2
const otherSource = of('World').pipe(
switchMap(x => `Hello ${x}!`)
);
otherSource.subscribe(x => console.log(`SOURCE (switchMap): ${x}`));
// SOURCE (switchMap): H
// SOURCE (switchMap): e
// SOURCE (switchMap): l
// SOURCE (switchMap): l
// SOURCE (switchMap): o
// SOURCE (switchMap):
// SOURCE (switchMap): W
// SOURCE (switchMap): o
// SOURCE (switchMap): r
// SOURCE (switchMap): l
// SOURCE (switchMap): d
// SOURCE (switchMap): !
哇!劳驾?刚刚发生了什么?
问题:这里的引擎盖下面到底是怎么回事?
让我们继续看另一组简单的示例,然后希望将所有内容捆绑在一起:
// OBJECT EXAMPLES
const foo = {
"first": 1,
"second": 2
}
// OBJECT EXAMPLE 1
Object.keys(foo).forEach(obj=>of(foo[obj]).pipe(
map(x=>x*2)
).subscribe(x => console.log(`SOURCE (map): ${x}`)))
// SOURCE (map): 2
// SOURCE (map): 4
好的,很公平。这似乎很简单
// OBJECT EXAMPLE 2
Object.keys(foo).forEach(obj=>of(foo[obj]).pipe(
switchMap(x=>of(x*2)) // WHY DO WE NEED ANOTHER "of()" HERE? "switchMap(x=>x*2)" DOESN'T COMPILE
).subscribe(x=> console.log(`SOURCE (switchMap): ${x}`)))
// SOURCE (switchMap): 2
// SOURCE (switchMap): 4
非常清楚,但是为什么我们需要向“ switchMap”提供“ of(x * 2)?”在STRING示例2中,“ switchMap”看起来像疯了似的,并自动将其输出包装为Observable(或者“ pipe” “将输出包装为Observable?),但是无论如何,“ switchMap”和“ pipe”不需要任何额外的“ of()”或任何其他将输出包装为Observable的帮助,但是在对象示例2中,我们明确需要提供第二个“ of()”以确保“ switchMap”的输出是可观察到的,否则代码不会编译。(但是对于“ map”,我们不需要提供第二个“ of()“)。再一次,为什么要区别呢?
因此,总而言之,如果有人可以解释,我将非常感激:
提前谢谢!
答案 0 :(得分:1)
对于您的示例运算符,这些是类型转换:
of
:接收类型为T
的参数,生成单个类型为T
的通知,然后完成map
:接收类型为T => R
的参数,每当接收到类型为R
的通知时,都会生成类型为T
的通知switchMap
收到类型为T => ObservableLike<R>
的参数,每当收到类型为R
的通知时,都会产生类型为T
的通知switchMap
具有投影函数,期望将ObservableLike<R>
作为返回类型。该语句的重要部分是Observable Like (可观察到的)。有时是违反直觉的,但是RxJS会在内部尽可能地在Observables中转换其他类型,例如:
在可以提供ObservableLike
的地方使用数组时,RxJS将数组视为值流。
例如,说我将这个数组转换为可观察的:
from([1, 2, 3])
我订阅的内容是:
// 1
// 2
// 3
由于string
只不过是Array<char>
,因此RxJS会尝试将此字符串转换为它的字符流。 (char
实际上不是JS中的数据类型,但内部字符串是数组)
即这些是相等的:
from(['a', 'b', 'c'])
from('abc')
ObservableLike
提供一个switchMap
,但是string
类型恰好是ObservableLike
-只是一个字符流。 / li>