1

考虑以下示例:


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允许取消先前的请求。我怎样才能只订阅最新的请求响应?

4

3 回答 3

1

您可以使用shareReplay()RxJS 的运算符。查看解决方案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);
});
于 2019-11-06T12:20:35.883 回答
0

似乎是exhaustMap操作员的工作

它在某种程度上与switchMap

如果使用 switchMap,挂起的后端请求将被中止,以支持最近分发的操作。然而,如果使用了 exhaustMap,当有一个挂起的后端请求时,分派的动作将被忽略。

还有可能适合您的运营商concatMapmergeMap为了了解它们之间的区别,请查看这篇很棒的文章:

于 2019-11-06T12:33:19.890 回答
0

最近的请求是什么时候?

你会在什么时间点定义最新的请求是什么?
您需要collect用户每次单击,然后在其他某个时间点执行请求。但这似乎很奇怪

一旦请求本身完成,每个可观察的 http 请求都将完成。如果您没有任何重叠的请求switchMap,则不会做任何事情,因为没有任何东西可以切换。
您可以验证是否添加延迟

请参阅https://stackblitz.com/edit/rxjs-about-switchmap-jhy3v4
如果您在请求中添加延迟以模拟延迟,您将获得预期的结果switchMap

没有延迟,您的请求是如此之快,一旦您再次单击它就完成了,并且没有什么可切换的,因为内部 observable 已经完成,因此您可以获得所有结果,因为它是一个新的事件流。
这也是为什么例如lasttakeLatest不会在这里提供帮助的原因。

这就是我想要
https://stackblitz.com/edit/rxjs-about-switchmap-jhy3v4

在带有 id test 的按钮中,我将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');
});

请注意RxJS:避免Oles Savluk 发布的与 switchMap 相关的错误。

于 2019-11-07T06:55:32.830 回答