Почему switchmap возвращает http-ответ, а map возвращает наблюдаемый - PullRequest
0 голосов
/ 04 сентября 2018

В этом примере switchMap выдает http-ответ, но при использовании map возвращается Observable. Я считаю, что это связано с «выравниванием» switchMap, но я до сих пор не понимаю, что делает SwitchMap за кулисами для получения результата HTTP-ответа.

import{Component, OnInit} from '@angular/core';
import {HttpClient} from '@angular/common/http';
import { of, from, Observable, forkJoin } from 'rxjs';
import { map, mergeMap, switchMap, tap, flatMap} from 'rxjs/operators';
@Component({
  selector: 'star-wars',
  template: ``,
})
export class StarWars {
  private peopleUrl = 'https://swapi.co/api/people/';

  constructor(private http: HttpClient) {}

  ngOnInit() {
    of(1)
    .pipe(
      map(() => this.http.get('https://swapi.co/api/people/1')),
      // produces Observable {_isScalar: false, source: {…}

      switchMap(() => this.http.get('https://swapi.co/api/people/1')),
      // produces http response {name: "Luke Skywalker", height: "172", mass: "77", hair_color: "blond"…}
    )
    .subscribe(res => {
      console.log(res)
    })
  }
}

Буду признателен за любые пояснения о том, что SwitchMap делает здесь для получения этого другого результата.

1 Ответ

0 голосов
/ 05 сентября 2018

«Сглаживание» в Observables аналогично понятию сглаживания массивов, с которым вы, возможно, уже знакомы.

Например:

[[0], [1, 2], [3]].flatten()
// output [0, 1, 2, 3]

В общем случае выравнивание означает взятие типа типов значений (например, массив массивов значений) и создание обратного типа значений (например, массив значений).

Типом типов иногда называют Тип высшего порядка (например, функция высшего порядка - это функция, возвращающая функцию, Наблюдаемый более высокого порядка - это Наблюдаемая из наблюдаемых). Таким образом, уплощение преобразует тип высшего порядка в тип первого порядка.

Написано на TypeScript flatten - это функция со следующей подписью:

flatten(source: Type<Type<Value>>): Type<Value>

В RxJS эквивалентно flatten равно mergeAll оператор:

of(of(0), of(1, 2), of(3)).pipe(mergeAll())
// produce Observable<number> -> [0, 1, 2, 3]

Комбинация map и flatten - это то, что часто называют flatMap, хотя имя может отличаться, основная концепция одна и та же - делать отображение и выравнивание как одно действие.

В контексте массива вместо:

[0, 1, 2, 3].map(x => Array(x).fill(x)).flatten()
// [[], [1], [2, 2], [3, 3, 3]].flatten()
// output: [1, 2, 2, 3, 3, 3]

Мы можем просто использовать:

[0, 1, 2, 3].flatMap(x => Array(x).fill(x))

RxJS имеет довольно много операторов, которые действуют как flatMap:

  • mergeMap - сглаживает наблюдаемые одновременно, поэтому входные и выходные значения могут быть потенциально в другом порядке
  • concatMap - последовательно сглаживает Observables по одному, поэтому входные и выходные значения будут в одинаковом порядке
  • switchMap - выравнивает наблюдаемое, но предоставляет только самое последнее значение

Обычно эти операторы типа flatMap просто вызовут subscribe в Observable, возвращаемом из функции отображения, и будут управлять основными подписками для нас.

...