Angular api повикване: Наблюдаемо срещу обещание

Имам тази услуга, която се обажда на API, за да получи куп описания на филми и връща Observable:

getNowPlayingMovies$(page: number, country?: string): Observable<NowPlaying> {
    console.log(`${this.baseUrl}${this.now_playing}?${this.key}&region=${country || 'US'}&page=${page}`);
    return this.http.get<NowPlaying>(
      `${this.baseUrl}${this.now_playing}?${this.key}&region=${country || 'US'}&page=${page}`
    );
  }

В компонента, който използва тази функция по-горе, аз я наричам промяна на стойността на страницата всеки път, за да мога да предложа на потребителя пагинация в изгледа на компонента.

И това е компонентът, който извиква услугата:

getNowPlayingMovies(): void {
    this.nowPlayingService.getNowPlayingMovies$(this.page).subscribe((data) => {
      this.nowPlaying.push(
        ...data.results.filter((result) => result.backdrop_path)
      );
      if(!this.last_page){
        this.last_page = data.total_pages
        this.page++;
      } else if(this.page <= data.total_pages) {
        this.page++;
      }
      console.log(data);
      console.log(this.nowPlaying);
    });
  }

Четох, че на Angular винаги трябва да се опитвате да работите с помощта на Observable, а не на Promises, но при сценарии като този не виждам никакво предимство да се абонирате за отговора на api call.

Би било правилно да трансформираме Observable в услугата в Promise като това?

getNowPlayingMovies$(page: number, country?: string): Promise<NowPlaying> {
    console.log(`${this.baseUrl}${this.now_playing}?${this.key}&region=${country || 'US'}&page=${page}`);
    return this.http.get<NowPlaying>(
      `${this.baseUrl}${this.now_playing}?${this.key}&region=${country || 'US'}&page=${page}`
    ).toPromise();
  }

Уча Angular и работя по това, за да го добавя към моето портфолио, така че искам да се науча да го правя по правилния и възможно най-добрия начин.


person kiewlovsky    schedule 11.04.2021    source източник
comment
вижте това stackoverflow.com/questions /63462672/   -  person Moshezauros    schedule 11.04.2021
comment
Да, работи и в двете посоки, но ще съм благодарен, ако някой с повече опит може да ми обясни къде е разликата и коя опция е по-подходяща   -  person kiewlovsky    schedule 11.04.2021


Отговори (1)


Няма да е неправилно, като: ще работи.

Губите някои функции при превод към Promise, но най-важната обикновено е без значение: според моя опит методите на http не връщат наблюдаеми, които излъчват множество стойности. Имайте предвид, че наблюдаемият API оставя тази възможност отворена. Можете да се разровите в подходящ източник, за да научите повече.

Една от причините, поради която много ресурси вероятно все още предполагат, че трябва да работите с наблюдаеми е, че много други функции в Angular са или могат/трябва да бъдат изградени с наблюдаеми. Помислете за работа с реактивни формуляри, комбиниране на множество http заявки, потребителски събития и т.н. Ако се придържате към използването на наблюдаеми за всички тях, RxJs ви предлага мощни (но въпреки това може би сложни и/или сложни) начини да ги комбинирате. Помислете например за:

  • http.get наблюдаем за извличане на филми
  • потребителят въвежда в поле за въвеждане, вероятно от piped до debounce
  • комбинирайки го с http.post за заявка за алтернативни филми
  • combineLatest всички тези и евентуално pipe чрез debounce или distinctUntilChanged за извършване на актуализации на потребителския интерфейс в точното време
  • и т.н.

Изграждането на всички тези взаимодействия, когато преобразувате http обаждания в Promise<T> веднага, ще бъде куп допълнителна работа и дори може да изглежда неидиоматично.

Като казах всичко това, понякога съм правил това, което описахте, и съм опростил услуга, като я накарах да връща обещания вместо наблюдаеми. Но в повечето случаи това може да изглежда добра идея в началото и ще направи нещата по-трудни по-късно.

person Jeroen    schedule 11.04.2021
comment
Благодаря, Йерун, това е обяснението, което търсех. И така, следвайки примера, който публикувах, може би най-добрият вариант е да върна наблюдаем от моята услуга, но може би в компонента да използвам оператора на канала, за да го трансформирам в обещание? Защото единственото, което мисля, когато се абонирам, е да запазя стойността на отговора в променлива. - person kiewlovsky; 11.04.2021
comment
да Въпреки че не съм сигурен защо вашият компонент би искал да го преобразува в Promise? Компонентът може просто да subscribe към резултата и да го използва, или можете да използвате канала async (който управлява абонирането/отписването вместо вас), за да видите директно филмите в компонента. - person Jeroen; 12.04.2021