使用异步/等待而不是订阅传递变量

时间:2020-11-08 03:12:40

标签: angular typescript async-await

我正在尝试使用async / await进行两次API调用,但是第二个async函数中的变量不起作用或Angular无法呈现。

const pokemon = this.httpClient
  .get(`https://pokeapi.co/api/v2/pokemon/${pokemon_name}`)
      .subscribe(pokemon => {
        this.image = pokemon["sprites"]["front_default"];
      });

我认为这是针对Angular组件的生命周期,但我不知道如何解决

https://stackblitz.com/edit/angular-http-async-await-q4m6d7?file=src%2Fapp%2Fapp.component.ts

1 个答案:

答案 0 :(得分:0)

在将可观察对象转换为应许对象时,我没有看到任何明确的用途。尤其是当涉及到链式请求时,最好使用可观察的对象并使用旨在在这些情况下提供帮助的RxJS运算符。

根据您的情况,您需要进行多项更改。

  1. 内部请求取决于外部请求的响应。您可以使用RxJS switchMap运算符在此处映射可观察对象。

  2. 外部请求返回一个URL数组,每个URL都需要单独触发以获取图像。在这里,您可以使用RxJS forkJoin函数来并行触发多个请求。

  3. 然后可以将结果映射到可以使用模板中的Angular async管道订阅的URL数组。

  4. 由于它是图像数组,因此可以使用*ngFor指令遍历它们。

控制器

import { Component, OnInit } from "@angular/core";
import { HttpClient } from "@angular/common/http";

import { Observable, forkJoin } from "rxjs";
import { switchMap, map } from "rxjs/operators";

@Component({ ... })
export class AppComponent implements OnInit {
  images: Observable<any>;

  constructor(private httpClient: HttpClient) {}

  ngOnInit() {
    this.doSometing();
  }

  doSometing() {
    this.images = this.httpClient
      .get("https://pokeapi.co/api/v2/pokemon?limit=151")
      .pipe(
        switchMap((pokemons: any) =>
          forkJoin(
            pokemons.results.map((result: any) =>
              this.httpClient
                .get(result.url)
                .pipe(map((pokemon: any) => pokemon.sprites.front_default))
            )
          )
        )
      );
  }
}

模板

<ng-container *ngIf="(images | async) as urls">
    <h1>Images</h1>
    <img *ngFor="let url of urls" [src]="url"/>
</ng-container>

我已经修改了您的Stackblitz


注意:toPromise()在RxJS 7中已弃用,在RxJS 8中已消失。