【问题标题】:asynchronisme problem to consum an existing api使用现有 api 的异步问题
【发布时间】:2018-12-30 06:03:40
【问题描述】:

我实际上是在使用现有的 Api 做一个 webApp:PokéAPI 问题是,我想获得所有口袋妖怪的名字并在第一时间打印出来。它有效!但是……不按顺序。我想要的是打印按 id 排序的口袋妖怪列表(第一个是bulbasaur 第二个ivysaure 等),有时ulbasaur 是列表中的第五个等等。我认为可以通过异步解决它并等待在互联网上搜索,但我可以'让它工作。

已经尝试过异步等待解决方案,但肯定是错误的方式。我不知道在哪里使用它们以及何时以及如何使用它们

===data.service.ts===

import { Injectable } from '@angular/core'
import { HttpClient } from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})
export class DataService {

  constructor(private http: HttpClient) { }

  getPokemons(id) {
    return this.http.get('https://pokeapi.co/api/v2/pokemon/' + id +'/')
   }
}

===home.component.ts===

import { Component, OnInit } from '@angular/core';
import { DataService } from '../data.service';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit {
  pokemons: any = [];

  constructor(private data: DataService) { }

  async ngOnInit() {
    for(var i=1; i<152; i++){
      await this.data.getPokemons(i).subscribe(data => {
        this.pokemons.push(data)
    })}

   console.log(this.pokemons)
  }

}

===home.component.html===

<p>
  home works!
</p>

<ul *ngIf="pokemons">
  <li *ngFor="let u of pokemons">
      {{u.name}}
  </li>

</ul>

预期:bulbasaur ivysaur venusaur 实际:charmender beedrill ivysaur(随机顺序)

编辑: 所以我检查了你的解决方案,也许我不明白,但我这样做了:

ngOnInit() {

forkJoin(
  [...Array(151)].map((_, i) => this.data.getPokemons(i + 1))
)
.subscribe(data => {
  this.pokemons = data;
  console.log(this.pokemons)
});
}

并在 console.log 上收到此错误:错误类型错误:“您在预期流的位置提供了 'undefined'。您可以提供 Observable、Promise、Array 或 Iterable。”

我认为问题在于地图功能中的“_”,在互联网上搜索并没有找到类似的东西。我们同意我不需要编写 loadAllAtOnce 函数,这只是一个示例?我希望我的问题不会让你烦恼,但是 [...Array(151)].map 的含义是什么? (什么是“...”)

编辑:有些东西很奇怪。我在网站顶部的导航栏中创建了一个新组件,因为我的列表位于主页组件中,我想将它放在另一个而不是主页中。并且只是为了测试我让列表也在家庭组件中。 当我从一个组件切换到另一个组件(家到 pokedex 或 pokedex 到家)时,我的列表按我想要的顺序排列。但是当我刷新同一个组件时,列表不再是良好的顺序。我不明白为什么,但也许这种精度可以帮助你......

【问题讨论】:

    标签: typescript rest api async-await


    【解决方案1】:

    解决方案是一次进行所有调用,然后等待所有调用都使用 forkJoin 完成。它将以与您提供给 forkJoin 函数的 observables 数组相同的顺序为您提供数组中的响应。

    看起来像这样:

    loadAllAtOnce(values: number[]) {
      return forkJoin(
        values.map(x => of (x).pipe(delay(x)))
      ).pipe(
        tap(values => {
          console.log(values);
    
        })
      );
    }
    

    您可以看到一个完整的示例here

    在您的情况下,代码如下所示:

    forkJoin(
        Array(151) // make an empty array with length 152
          .fill(0) // fill it with zeros
          .map((_, i) => this.data.getPockemons(i + 1)) // _ means ignore the parameter
      )
      .subscribe(pockemons => {
        this.pockemons = pockemons;
        console.log(this.pokemons)
      });
    

    你可以找到这个here的例子。

    【讨论】:

    • 谢谢!我稍后会尝试并告诉你它是否有效!再次感谢您的宝贵时间:)
    • 我编辑了我的帖子,如果你能帮助我:) 再次感谢
    • 嘿,在由于某种原因未填充的数组上使用 map 似乎存在问题。我更新了答案,只用零填充数组。 :)
    • 非常感谢!它有效:) 再次感谢您抽出宝贵的时间,有没有办法解决这个问题?我有一些关于网络开发的问题,你似乎比我更了解这一点,有什么地方可以谈谈吗?如果我犯了错误,再次感谢我的英语,再见:)
    • 你应该在分数附近的答案上有一个复选标记。至于聊天,你可以在这里找到我。 discord.gg/SpW9jfP
    猜你喜欢
    • 2011-06-06
    • 2021-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-29
    • 1970-01-01
    • 1970-01-01
    • 2021-12-18
    相关资源
    最近更新 更多