地图 vs 合并地图 vs 切换地图
map`and`、mergeMap`or` 和switchMap`or` 是 RxJS 中的三个主要操作符,你会经常用到它们。因此,了解它们的作用和区别至关重要。
地图
map是 Observable 中最常用的操作符。它的作用与数组中的 map 操作符非常相似。它map会接收 Observable 发出的每个值,对其执行操作,并返回一个 Observable(以便 Observable 链可以继续)。
可以把它想象成一个函数,它接受原始值和一个投影。该函数将投影应用于这些值,并返回转换后的值。
举个例子。假设我们有一个数组类型的可观察对象。这个数组包含一系列人物信息。每个人物都由一个对象表示,并且每个人都有自己的名字和最喜欢的角色。我们只想知道所有人物的列表。
import { of } from 'rxjs';
import { map } from 'rxjs/operators';
const observable = of([
{
name: "Parwinder",
character: "Calcifer"
},
{
name: "Laure",
character: "Alchemist"
},
{
name: "Eliu",
character: "X-Men"
},
{
name: "Robert",
character: "Link"
}
]);
observable.pipe(
map(arr => arr.map(person => person.character)) // loops over objects and returns characters
).subscribe(
char => console.log(char) // ["Calcifer", "Alchemist", "X-Men", "Link"]
);
合并地图
mergeMapmerge是 Observable和.的组合map。有时,你的map. 或 . 投影会生成多个 Observable。例如,现在我有一个字符数组,对于每个字符,我想调用后端服务并获取一些信息。
import { of, from } from 'rxjs';
import { map } from 'rxjs/operators';
const dummyApi = (character) => { // fake api call function
return of(`API response for character: ${character}`).pipe(
delay(1000) // the fake api takes 1 second
);
}
from(["Calcifer", "Alchemist", "X-Men", "Link"]) // characters I need to get information for
.pipe(
map(arr => dummyApi(arr)) // generates 4 new Observables
).subscribe( // subscribing Observable (outer) of 4 Observables (inner)
data => data.subscribe(i => console.log(i)) // subscribing to inner Observables
)
输出:
API response for character: Calcifer
API response for character: Alchemist
API response for character: X-Men
API response for character: Link
它奏效了。输出结果符合预期。你看出问题所在了吗?我们先订阅了map提供的 Observable,然后在subscribe代码块内又订阅了 API 调用提供的每个 Observable。这种方法虽然可行,但并不理想。这就是它的作用所在mergeMap。正如我所说,它能够映射和合并!
import { of, from } from 'rxjs';
import { mergeMap } from 'rxjs/operators';
const dummyApi = (character) => {
return of(`API response for character: ${character}`)..pipe(
delay(1000)
);
}
from(["Calcifer", "Alchemist", "X-Men", "Link"])
.pipe(
mergeMap(arr => dummyApi(arr)) // gets 4 Observable as API response and merges them
).subscribe( // we subscribe to one mapped and merged Observable
data => console.log(data)
)
挺不错的,对吧!
切换地图
switchMap它的功能与之前类似mergeMap,但略有不同。switchMap它会订阅外部 Observable 内部的所有 Observable,但不会合并这些内部 Observable。相反,它会切换到最新的Observable 并将其传递给链式调用。
它仍然提供一个 Observable 作为输出,不是通过合并,而是通过只发出最新 Observable 的结果。
对于我们最后一个示例,如果我们使用它,switchMap 我们将只能获得最后一个 Observable 的结果。
import { of, from } from 'rxjs';
import { switchMap, delay } from 'rxjs/operators';
const dummyApi = (character) => {
return of(`API response for character: ${character}`).pipe(
delay(1000)
);
}
from(["Calcifer", "Alchemist", "X-Men", "Link"])
.pipe(
switchMap(arr => dummyApi(arr))
).subscribe(
data => console.log(data) // API response for character: Link
)
有些情况下,switchMapExcel 可以发挥出色作用。例如,在输入框中,我们可以根据最终用户输入的内容(通过调用 API 获取输入字段中的文本)向他们提供建议。
如果用户搜索“Chase”,他们开始输入“C”,我们就发起一个调用。当他们输入“h”时,我们需要再次发起调用以获取“Ch”。此时,我们之前调用的值为“C”的 Observable 对我们毫无用处。我们应该取消该 Observable,并订阅“Ch”Observable。我们需要切换到最新的 Observable!
import { of, from } from 'rxjs';
import { switchMap, delay } from 'rxjs/operators';
const dummyApi = (character) => {
return of(`Search result for keyword: ${character}`).pipe(
delay(1000)
);
}
from(["C", "Ch", "Cha", "Chas", "Chase"]) // mimic key input in text field
.pipe(
switchMap(arr => dummyApi(arr))
).subscribe(
data => console.log(data) // Search result for keyword: Chase
)
我们只得到了“Chase”可观测对象的结果,而这正是我们想要的!
祝您编程愉快👋🏼
文章来源:https://dev.to/bhagatparwinder/map-vs-mergemap-vs-switchmap-5gee