考虑以下示例:
import { fromEvent } from 'rxjs';
import { switchMap, tap } from 'rxjs/operators';
import { ajax } from 'rxjs/ajax';
const httpCall$ = ajax.getJSON('https://rickandmortyapi.com/api/character/');
const click$ = fromEvent(document, 'click');
const switchMapExample$ = click$.pipe(
tap(() => console.log('inside switchMap - click happend')),
switchMap(() => {
console.log('inside switchMap - start http request');
return httpCall$.pipe(
tap((val) => console.log('inside switchMap - http response ', val))
);
}
));
switchMapExample$.subscribe((val) => {
console.table(val); // Is There a way to log only the latest value ?
});
通过在文档内部单击,它正在处理新请求。
在此处查看闪电战:rxjs-about-switchmap
使用SwitchMap
可以取消先前的请求。我如何只订阅最新的请求响应?
答案 0 :(得分:1)
您可以使用RxJS的shareReplay()
运算符。查看解决方案https://stackblitz.com/edit/rxjs-about-switchmap-9blsbq。
import { fromEvent } from "rxjs";
import { switchMap, tap, shareReplay } from "rxjs/operators";
import { ajax } from "rxjs/ajax";
const httpCall$ = ajax
.getJSON("https://rickandmortyapi.com/api/character/")
.pipe(
tap(() => console.log("http request")),
shareReplay(1),
tap(() => console.log("http response"))
);
const click$ = fromEvent(document, "click").pipe(
tap(() => console.log("click happend"))
);
const switchMapExample$ = click$.pipe(switchMap(() => httpCall$));
switchMapExample$.subscribe(val => {
console.log(val);
});
答案 1 :(得分:0)
似乎是exhaustMap
operator的工作
与switchMap
相反:
如果使用switchMap,则挂起的后端请求将被中止,转而使用最近分发的操作。但是,如果使用了exhaustMap,则在有待处理的后端请求时,将忽略调度的操作。
还有concatMap
和mergeMap
个运算符可能对您有用。为了了解它们之间的区别,请看这篇很棒的文章:
答案 2 :(得分:0)
最近的请求是什么时候?
您将在什么时间定义最新请求?
您需要collect
用户每次单击,然后在其他时候执行请求。但这看起来很奇怪
请求本身完成后,每个可观察到的http请求都会完成。
如果您没有任何重叠的请求,switchMap
不会做任何事情,因为没有任何可切换的内容。
您可以验证是否添加了延迟
请参见https://stackblitz.com/edit/rxjs-about-switchmap-jhy3v4
如果您在请求中添加延迟以模拟延迟,那么您将从switchMap
在没有延迟的情况下,您的请求是如此之快,以至于您再次单击就可以完成,并且因为内在的可观测对象已经完成而没有任何切换,因此您得到了所有结果,因为它是新的事件流。 >
这也是为什么last
或takeLatest
在这里无济于事的原因。
这就是我要
https://stackblitz.com/edit/rxjs-about-switchmap-jhy3v4
在ID测试按钮中,我将debounceTime
与switchMap
结合使用并启用/禁用按钮
const click3$ = fromEvent(document.querySelector('#test'), 'click');
switchMapExample2$.subscribe((val) => {
console.table(val);
});
const button = document.querySelector('#test');
const switchMapExample3$ = click3$.pipe(
tap(() => button.setAttribute('disabled', 'disabled')),
debounceTime(500),
tap(() => console.log('inside switchMap - click happend')),
switchMap(() => {
console.log('inside switchMap - start http request');
return httpCall$.pipe(
tap((val) => console.log('inside switchMap - http response ', val))
);
}));
switchMapExample3$.subscribe((val) => {
console.table(val);
button.removeAttribute('disabled');
});
请注意Oles Savluk发布的RxJS: Avoiding switchMap-Related Bugs。