Kri*_*han 17
两个运营商是不同的。
switchMap:将值映射到 observable。取消之前的内部 observable。
fromEvent(document, 'click')
.pipe(
// restart counter on every click
// First click: 0, 1, 2...
// Second click: cancels the previous interval and starts new one. 0, 1, 2...
switchMap(() => interval(1000))
)
.subscribe(console.log);
Run Code Online (Sandbox Code Playgroud)
map:为每个值添加投影。
//add 10 to each value
const example = source.pipe(map(val => val + 10));
Run Code Online (Sandbox Code Playgroud)
Viv*_*mar 14
Map - 它的作用与数组中的map相对相似。map接收从 发出的每个值Observable,对其执行操作。
var observable = Rx.Observable.interval(1000);\nvar observer = {\n next: function(value) {\n console.log(value);\n }\n};\n\nobservable.map(function(value) {\n return value*10; \n}).subscribe(observer);\n\nRun Code Online (Sandbox Code Playgroud)\nSwitchMap - switchMap 将订阅外部 Observable 内的所有内部 Observable,但不会合并内部 Observable。相反,它会切换到最新的 Observable 并将其传递到链中。
\n\n让\xe2\x80\x99s 假设顶部的每条橙色垂直线代表 1 秒。这意味着外部 Observable (OO) 在 1、4 和 5.5 秒处发出值,而内部 Observable (IO) 在 3 秒内每秒发出值,在订阅后立即开始(时间为零)。
\n前三个输出值(10、10、10)看起来非常简单。只需根据运算符逻辑将它们分别乘以 1 x 10 = 10 即可。根据前三个值,我们可以说对于每个 OO 值,IO 都会发出其所有值。
\n这个假设对于第一个输出值 30\xe2\x80\xa6 和第二个输出值 30\xe2\x80\xa6 似乎成立
\n但\xe2\x80\x99t 它应该发出最终值 30 吗?
\n这就是 switchMap 逻辑发挥作用的地方。每次 OO 发出一个值时,IO 都会发出其所有值,除非 OO 在 IO 发出其所有值之前发出新值。当 OO 发出值 5 时,我们可以看到这一点,并且我们的最后一个值 30 似乎是 \xe2\x80\x9ccanceled\xe2\x80\x9d。
\n\n\n\n将每个源值投影到一个 Observable,该 Observable 合并到输出 Observable 中,仅从最近投影的 Observable 发出值。
\n
var button = document.querySelector(\'button\');\n\nvar obs1 = Rx.Observable.fromEvent(button, \'click\');\nvar obs2 = Rx.Observable.interval(1000);\n\nobs1.switchMap(\n event => {\n return obs2\n }\n).subscribe(\n (value) => console.log(value)\n);\n\nRun Code Online (Sandbox Code Playgroud)\n在上面的例子中,无论我点击按钮多少次,我总是会得到从 0 开始的值,因为switchMap切换到最新的可观察值。
最佳用例是当我们想要根据从外部可观察到的数据进行 API 调用时。
\n阅读更多 -
\nhttps://zach-gollwitzer.medium.com/how-to-read-an-rxjs-marble-diagram-f6e8dfa29781 \n https://dev.to/bhagatparwinder/map-vs-mergemap-vs-switchmap-5gee \n https://blogs.msmvps.com/deborahk/higher-order-observable/
\n是否在某些情况下它根本没有区别?
不,它们是两种完全不同的野兽。switchMap预期返回一个 observable,map可以返回任何东西。它们的应用是不同的。它通常是这样的:
someStream$.pipe(
switchMap(args => makeApiCall(args)), // must return a stream
map(response => process(response)) // returns a value of any shape, usually an object or a primitive
).subscribe(doSomethingWithResults);
Run Code Online (Sandbox Code Playgroud)
还有其他性质类似于switchMap: mergeMap(AKA flatMap), exhaustMap, 的运算符concatMap(有些情况下,所有这些或多或少是相同的),但不是map。
查看2个函数的定义:
map<inputType, outputType>(syncFunction: (input: inputType) => outputType )
switchmap<inputType, Observable<outputType>>( asyncFunction: (input: inputType) => Observable<outputType> )
Run Code Online (Sandbox Code Playgroud)
map = 异步函数调用同步函数 (asyncTask =>syncTask)
switchMap = 异步函数按顺序调用异步函数(asyncTask => asyncTask )
switchMap 的示例:
observable1 calls observable2 means:
observable1_event1 => new observable2 asynchronous => Task1
observable1_event2 => new observable2 asynchronous => Task2
observable1_event3 ...
Run Code Online (Sandbox Code Playgroud)
如果在task1未完成时发出observable1_event2,则task1的Observable2将通过调用unsubscribe()被拒绝。这意味着任务 1 之后将不再显示输出。
如果在任务 1 完成时发出 observable1_event2。Task1 的所有输出将正常显示,然后任务2 的输出将显示。
请注意:每个新的 observable2 都可以触发许多事件(observable2_event1、observable2_event2,...)