您可以使用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);
});
,
似乎是exhaustMap
operator的工作
与switchMap
相反:
如果使用switchMap,则挂起的后端请求将被中止,转而使用最近分发的操作。但是,如果使用了exhaustMap,则在有待处理的后端请求时,将忽略调度的操作。
还有concatMap
和mergeMap
个运算符可能对您有用。为了了解它们之间的区别,请看这篇很棒的文章:
,
最近的请求是什么时候?
您将在什么时间定义最新请求?
您需要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。
本文链接:https://www.f2er.com/3152840.html