Почему switchMap не отменяет повторный запрос? - PullRequest
0 голосов
/ 25 апреля 2020

Запрос выполняется на сервере:

ngOnInit(): void {
    this.route.paramMap
      .pipe(
        switchMap((params) => {
          return this.spdModelManagerService
            .getSpdModelManager()
            .getOrderDefinitionVersions(params.get("orderid"));
        }),

        finalize(() => {
        })
      )
      .subscribe((data) => {
        console.log("aa");
      });
  }

Если вы выполняете f5 много раз или go по маршруту, запросы всегда отправляются на сервер и не отменяются switchMap ((params) => {}). На все запросы приходит ответ.

Стоит ли использовать распознаватели или как? Если пользователь много раз запрашивает маршрут, он отправляет много запросов

1 Ответ

1 голос
/ 26 апреля 2020

Это своего рода хак, но это похоже на то, что я делал при кэшировании определенных запросов. По сути, если входные данные для get одинаковы, а ответ всегда будет одинаковым, вы можете кэшировать наблюдаемое внутри свойства службы и использовать shareReplay, чтобы просто переслать последнее переданное значение. Затем, если входные данные изменяются, перезапись свойства приводит к тому, что новая наблюдаемая разрешается для возврата нового значения.

пример службы

import { Injectable } from "@angular/core";
import { Observable, timer, of } from "rxjs";
import { publishReplay, map, shareReplay } from "rxjs/operators";

@Injectable()
export class ExampleService {
  private savedObs$: Observable<any>;
  private lastId: number;

  constructor() {}

  get(id: number) {
    const randomReturnValue = Math.random();

    if (this.lastId !== id) {
      this.lastId = id;
      this.savedObs$ = of(id).pipe(
        shareReplay(1),
        map(x => randomReturnValue)
      );
    }

    return this.savedObs$;
  }
}

компонент

import { Component } from '@angular/core';
import { ExampleService } from './example.service';
import { tap } from 'rxjs/operators';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  name = 'Angular';

  constructor(private exampleService: ExampleService) {
    // To show that the same value is returned for the first 7 calls to the observable
    for (let i = 0; i < 15; i += 1) {
      if (i < 7) {
        this.exampleService.get(1).pipe(
          tap(x => {
            console.log(x);
          })
        ).subscribe();
      } else {
        this.exampleService.get(i).subscribe(x => {
          console.log(x);
        });
      }
    }

  }
}

Если вы откройте консоль в Stackblitz, и вы увидите, что одно и то же значение возвращается для первых семи вызовов из-за идентичного идентификатора, а затем изменяется каждый раз, когда передается новый идентификатор. По общему признанию это - немного клуджа, но это может дать вам то, что вам нужно.

https://stackblitz.com/edit/angular-6dioyr

...