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);
      });