首页 > 解决方案 > 将 promise.all 的结果推送到数组中

问题描述

我目前正在挣扎,因为标题会暗示我正在尝试做的事情。我对正在发生的事情有所了解,尽管我无法让它 100% 地按照我的意愿工作。

我的问题

在我的所有承诺都得到解决后,我想返回一个包含所有响应数据的数组。但是由于某种原因,当我在承诺之外返回口袋妖怪时,我得到的只是一个空数组。然而,在你看到的承诺中,我在第 5 次之后得到了我想要的包含 5 个对象的数组。有趣的部分是在我的主要功能 Pokegame 中,我还控制台登录 teamOne。但是,我得到一个空数组(“[]”),但与控制台日志“内部”具有相同的属性,但是我无法访问此数组中的键。我尝试了不同的方法,但由于某种原因,我无法从函数 getPokemons 返回“正常”数组。

代码

import React from "react";
import Pokedex from "./Pokedex";
import Pokecard from "./Pokecard";

var PokeAPI = "https://pokeapi.co/api/v2/pokemon/";

const getPokemonIDs = () => {
  var team = [];
  while (team.length < 5) {
    var randomPokemonID = Math.ceil(Math.random() * 807);
    team.push(randomPokemonID);
  }
  return team;
};

const getPokemons = () => {
  var pokemonIDs = getPokemonIDs();
  var pokemons = [];
  Promise.all(pokemonIDs).then(pokemonIDs => {
    for (let x in pokemonIDs) {
      fetch(PokeAPI + pokemonIDs[x])
        .then(response => response.json())
        .then(response => {
          pokemons.push(response);
          console.log("===inside===");
          console.log(pokemons);
        })
        .catch(error => {
          console.log(error);
        });
    }
  });
  console.log("==end==");
  console.log(pokemons.length);
  return pokemons;
};

const Pokegame = () => {
  const teamOne = getPokemons();
  console.log("==teamOne===")
  console.log(teamOne);

  return (
    <div>
      <Pokedex team={teamOne} />
    </div>
  );
};

export default Pokegame;

控制台输出

    ===inside===
    index.js:27 (5) [{…}, {…}, {…}, {…}, {…}]
    index.js:27 ==end==
    index.js:27 0

    ===teamOne===
    index.js:27 []
    0: {abilities: Array(2), base_experience: 63, forms: Array(1), game_indices: Array(0), height: 3, …}
    1: {abilities: Array(1), base_experience: 72, forms: Array(1), game_indices: Array(20), height: 6, …}
    2: {abilities: Array(3), base_experience: 175, forms: Array(1), game_indices: Array(9), height: 13, …}
    3: {abilities: Array(3), base_experience: 81, forms: Array(1), game_indices: Array(17), height: 5, …}
    4: {abilities: Array(2), base_experience: 238, forms: Array(1), game_indices: Array(4), height: 16, …}
    length: 5
    __proto__: Array(0)

    index.js:27 ===inside===
    index.js:27 [{…}]

    index.js:27 ===inside===
    index.js:27 (2) [{…}, {…}]

    index.js:27 ===inside===
    index.js:27 (3) [{…}, {…}, {…}]

    index.js:27 ===inside===
    index.js:27 (4) [{…}, {…}, {…}, {…}]

    index.js:27 ===inside===
    index.js:27 (5) [{…}, {…}, {…}, {…}, {…}]
    0: {abilities: Array(2), base_experience: 63, forms: Array(1), game_indices: Array(0), height: 3, …}
    1: {abilities: Array(1), base_experience: 72, forms: Array(1), game_indices: Array(20), height: 6, …}
    2: {abilities: Array(3), base_experience: 175, forms: Array(1), game_indices: Array(9), height: 13, …}
    3: {abilities: Array(3), base_experience: 81, forms: Array(1), game_indices: Array(17), height: 5, …}
    4: {abilities: Array(2), base_experience: 238, forms: Array(1), game_indices: Array(4), height: 16, …}
    length: 5
    __proto__: Array(0)

猜测

所以我知道承诺将被放入回调队列堆栈,这就是为什么它第一次返回一个空数组,但是我不明白为什么控制台日志 teamOne 甚至控制台日志口袋妖怪会记录一个具有类似属性的空数组?

代码沙盒

编辑主管共振iq1h2

标签: javascriptarraysreactjspromisefetch

解决方案


除了 Lada 所说的Promise.allAFAIK,如果你想异步更新你的模型,你可能需要useEffect使用useState

import React from "react";
import Pokedex from "./Pokedex";
// import Pokecard from "./Pokecard";
import { useEffect, useState } from "react";

var PokeAPI = "https://pokeapi.co/api/v2/pokemon/";

const getPokemonIDs = () => {
  var team = [];
  while (team.length < 5) {
    var randomPokemonID = Math.ceil(Math.random() * 807);
    team.push(randomPokemonID);
  }
  return team;
};

const getPokemons = () => {
  var pokemonIDs = getPokemonIDs();
  return Promise.all(
    pokemonIDs.map(pokemonId =>
      fetch(PokeAPI + pokemonId)
        .then(response => response.json())
        .then(response => {
          console.log("===inside===");
          return response;
        })
    )
  );
};

const Pokegame = () => {
  const [teamOne, setTeamOne] = useState([]);

  console.log(teamOne);
  useEffect(() => {
    getPokemons().then(team1 => {
      console.log(team1);
      setTeamOne(team1);
    });
  }, []);
  return (
    <div>
      <Pokedex team={teamOne} />
    </div>
  );
};

export default Pokegame;

https://codesandbox.io/s/bold-sound-uoo6v?file=/src/components/Pokedex.js


推荐阅读