Angular 有没有办法只订阅SwitchMap的最新响应?
考虑以下示例:Angular 有没有办法只订阅SwitchMap的最新响应?,angular,rxjs,observable,switchmap,Angular,Rxjs,Observable,Switchmap,考虑以下示例: 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');
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 ?
});
通过在文档内部单击,它将处理一个新请求
请参见此处的闪电战:
使用
SwitchMap
允许取消以前的请求。如何仅订阅最新的请求响应?您可以使用RxJS的shareReplay()
操作符。查看解决方案
似乎是一份适合你的工作
它在某种程度上与开关映射相反:
如果使用switchMap,将中止挂起的后端请求,以支持最近调度的操作。但是,如果使用exhaustMap,则当存在挂起的后端请求时,将忽略已调度的操作
还有可能适合您的concatMap
和mergeMap
操作符。为了了解它们之间的区别,请看这篇很棒的文章:
- 最新请求是什么时候
您将在什么时间点定义最新的请求?
您需要
收集
用户所做的每一次单击,并在其他点执行请求。但这似乎很奇怪
一旦请求本身完成,每个可观察到的http请求都将完成。
如果您没有任何重叠的请求,switchMap
将不会执行任何操作,因为没有任何东西可以切换。如果添加延迟,则可以验证 见
如果在请求中添加延迟以模拟延迟,则会得到
switchMap
如果没有延迟,您的请求会很快完成,只要您再次单击,就可以完成,并且没有任何东西可以切换,因为内部可观察对象已经完成,因此您可以获得所有结果,因为这是一个新的事件流。这也是为什么例如
last
或takeLatest
在这里没有帮助的原因
以下是我想做的在id按钮测试中,我将使用
debounceTime
与switchMap
结合使用,并启用/禁用按钮
constclick3$=fromEvent(document.querySelector('test'),'click');
switchMapExample2$.subscribe((val)=>{
控制台.工作台(val);
});
const button=document.querySelector(“#test”);
const switchMapExample3$=单击3$.管道(
轻触(()=>button.setAttribute('disabled','disabled'),
去BounceTime(500),
轻触(()=>console.log('insideswitchmap-单击happend'),
开关映射(()=>{
log('内部开关映射-启动http请求');
返回httpCall$.pipe(
点击((val)=>console.log('insideswitchmap-httpresponse',val))
);
}));
switchMapExample3$.subscribe((val)=>{
控制台.工作台(val);
按钮。删除属性(“禁用”);
});
只需注意由Savluk发布的消息 代码是否已经向您提供了最新的请求响应?在这种情况下,是的……但是如果请求花费的时间太长或者用户单击的速度太快,它会发出其他值……但是我只想要最新完成的请求值目标是什么?获取最新响应或只是确保快速单击的用户没有滥发http请求?获取最新响应。。。每次点击都会发送一个新的请求。。。使用switchMap允许我取消以前的请求..但只想订阅最后一个完成的请求。这是一个奇怪的要求,如果它是一个挂起的请求,您取消它并替换为最后一个结果,那么以前的结果如何成为最新的结果,因为您停止了检索最新的结果。如果结果总是比单击时间长,则您始终拥有旧结果。感谢您的回复<代码> LSTATE()/<代码>不能适合这里,因为它只发出最后一个值。但是考虑用户点击得太快。它只会发出初始的最后一个值,在这种情况下,您可以使用<代码> SaleRePype()/Cuffe >,检查解决方案。
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);
});