【问题标题】:Hi! I'm learning JS. When I append the pokemon to the div PokGen1,2,3 etc. The order of the pokemon is wrong how can I fix this?你好!我正在学习JS。当我将口袋妖怪附加到 div PokGen1,2,3 等时。口袋妖怪的顺序错误我该如何解决这个问题?
【发布时间】:2021-12-08 13:37:52
【问题描述】:

这些是我创建的函数

函数 prova 在 for 循环中进行提取,然后使用我要显示的内容的值创建各种变量

 function prova() {
    //Ciclo la fetch per avere solamente i pokemon di settima generazione
    for (let index = 1; index < 899; index++) {
      const id = index;
      fetch(
        `https://pokeapi.co/api/v2/pokemon/${id}/`,
        { method: "GET" }
        //Attendo la risposta del server
      ).then(async (response) => {
        //do il valore dei vari oggetti alle variabili
        let rispostaFetch = await response.json();
        let pokemonNumber = rispostaFetch.id;
        let pokemonName = rispostaFetch.name.charAt(0).toUpperCase() + rispostaFetch.name.slice(1); //Rendo maiuscola solo la prima lettera
        //Do il valore a pokemontypes di un nuovo array contente gli elementi dell'array pokemontypes.type.name con il metodo .map()
        let pokemontypes=rispostaFetch.types.map((pokemontypes) => pokemontypes.type.name)
        let pokemontype1 = pokemontypes[0];
        let pokemontype2 =pokemontypes[1];
        Card(pokemontype1,pokemontype2,pokemonNumber,pokemonName);
    });
    }
}

Card 函数创建 div,然后将 appendchild 添加到 pokGen div

        function Card(pokemontype1,pokemontype2,pokemonNumber,pokemonName) {
      //creo dinamicamente un Div con classe .pokemonCard + il risultato della funzione ActiveTypeSecond che dinamicamente mette il tipo di carta (fuoco, erba)
      // e metto come id #pokemon#+ la variabile pokemonNumber (il risultato sarà: #pokemon#1 ecc)
        let pokemonWrapper = document.createElement('div');
        pokemonWrapper.classList.add("pokemonCard", ActiveTypeSecond(pokemontype1.toLowerCase()));
        pokemonWrapper.id ='pokemon#'+pokemonNumber;
        //All'interno di questo div avrà quanto segue:
        pokemonWrapper.innerHTML = `
            <div class="pokemonPicture">
              <img class="pokemonImage" src="https://assets.pokemon.com/assets/cms2/img/pokedex/full/${ActiveLink(pokemonNumber)}.png" alt="">
           </div>
          <div class="pokemonName&Number">
            <span class ="numeroPokemon">N°${pokemonNumber}</span>
            <h3 class ="nomePokemon">${pokemonName}</h3> 
          </div>
          <div class="pokemonTipo">
            <ul class="pokemonlista">
              <li class="pokemonType">Type:</li>
              <span class="separatore"></span>
              ${Type2Pokemon(pokemontype1,pokemontype2,)}
            </ul>
          </div>`; 
          
      if (pokemonNumber <152) {
        const pokGen1 = document.getElementById('PrimaGen')
        pokGen1.appendChild(pokemonWrapper)
    
        pagina.appendChild(pokGen1)
      } 
      if (pokemonNumber > 151 && pokemonNumber < 252) {
        const pokGen2 = document.getElementById('SecondaGen')
        pokGen2.appendChild(pokemonWrapper)
    
        pagina.appendChild(pokGen2)
      } 
      if (pokemonNumber > 251 && pokemonNumber < 387) {
        const pokGen3 = document.getElementById('TerzaGen')
        pokGen3.appendChild(pokemonWrapper)
    
        pagina.appendChild(pokGen3)
      } 
      if (pokemonNumber > 386 && pokemonNumber < 494) {
        const pokGen4 = document.getElementById('QuartaGen')
        pokGen4.appendChild(pokemonWrapper)
    
        pagina.appendChild(pokGen4)
      } 
      if (pokemonNumber > 493 && pokemonNumber < 650) {
        const pokGen5 = document.getElementById('QuintaGen')
        pokGen5.appendChild(pokemonWrapper)
    
        pagina.appendChild(pokGen5)
      } 
      if (pokemonNumber > 649 && pokemonNumber < 722) {
        const pokGen6 = document.getElementById('SestaGen')
        pokGen6.appendChild(pokemonWrapper)
    
        pagina.appendChild(pokGen6)
      } 
      if (pokemonNumber > 722 && pokemonNumber < 810) {
        const pokGen7 = document.getElementById('SettimaGen')
        pokGen7.appendChild(pokemonWrapper)
    
        pagina.appendChild(pokGen7)
      }

 
  if (pokemonNumber > 809 && pokemonNumber < 899) {
    const pokGen8 = document.getElementById('OttavaGen')
    pokGen8.appendChild(pokemonWrapper)

    pagina.appendChild(pokGen8)
  }

}

各种 appendchild 之后 div 的顺序不对,如何解决?

【问题讨论】:

  • 请尝试创建一个最小的可重现示例。您也可以使用 Javascript/HTML/CSS sn-p(从左到右第 7 个图标)

标签: javascript html api


【解决方案1】:

欢迎来到异步世界!

您同时发送 898 个调用,但每次调用从服务器获得响应时,都会评估 then(async (response) =&gt; { } 中的代码。

但是,您无法控制哪个呼叫先到达。如果您希望它们已经按顺序排列,则需要等待第一个调用完成,然后再启动另一个。

否则,当您收到每个响应时,您会将口袋妖怪插入正确的位置。

更好的端点

如果您需要很多资源(假设超过 10 个),为每个资源发送单个请求通常不是一个好习惯。如果您可以控制后端,则最好创建一个端点来提供多个结果。

据我所知,pokeapi 有 Generations 端点。

你可能想用那个:)

(例如https://pokeapi.co/api/v2/generation/1

【讨论】:

  • ...好吧,在开始新的承诺之前等待承诺完成有点疯狂 - 而是(可以这么说)“模式” -> aka 'Resolve promises one-by-one'(取决于在rispostaFetch.id 或 smt) 上可以使用 ...
  • 是的,已经更新了答案:)
【解决方案2】:

fetch 调用您的回调函数 (.then(async (response) =&gt; {...}) 以返回数据 asynchronously。这会导致您的请求(确切地说是 898 个)不是按照您请求的顺序解决,而是在数据发送给您并准备就绪时解决。

我强烈建议您查看 https://javascript.info/promise-basics(或有关 Promise 的其他教程)以了解异步执行和 Promise 在 JavaScript 中的工作原理。

如何为您的代码解决此问题:

  1. 在请求另一个请求之前等待每个请求。
async function prova() {
  for (let index = 1; index < 899; index++) {
    const id = index;
    const response = await fetch(
      `https://pokeapi.co/api/v2/pokemon/${id}/`,
      { method: "GET" }
      //Attendo la risposta del server
    );
    //do il valore dei vari oggetti alle variabili
    let rispostaFetch = await response.json();
    let pokemonNumber = rispostaFetch.id;
    let pokemonName = rispostaFetch.name.charAt(0).toUpperCase() + rispostaFetch.name.slice(1); //Rendo maiuscola solo la prima lettera
    //Do il valore a pokemontypes di un nuovo array contente gli elementi dell'array pokemontypes.type.name con il metodo .map()
    let pokemontypes=rispostaFetch.types.map((pokemontypes) => pokemontypes.type.name)
    let pokemontype1 = pokemontypes[0];
    let pokemontype2 =pokemontypes[1];
    Card(pokemontype1,pokemontype2,pokemonNumber,pokemonName);
  }
}
  1. 等待所有请求完成,然后处理它们。
async function prova() {
  // collect returned promises of fetch
  let pendingResponses = [];
  for (let index = 1; index < 899; index++) {
    const id = index;
    const promise = fetch(
      `https://pokeapi.co/api/v2/pokemon/${id}/`,
      { method: "GET" }
      //Attendo la risposta del server
    );
    pendingResponses.push(promise);
  }
  // await them all
  const responses = await Promise.all(pendingResponses);
  // process the returned list of responses
  for (const response of responses) {
    //do il valore dei vari oggetti alle variabili
    let rispostaFetch = await response.json();
    let pokemonNumber = rispostaFetch.id;
    let pokemonName = rispostaFetch.name.charAt(0).toUpperCase() + rispostaFetch.name.slice(1); //Rendo maiuscola solo la prima lettera
    //Do il valore a pokemontypes di un nuovo array contente gli elementi dell'array pokemontypes.type.name con il metodo .map()
    let pokemontypes=rispostaFetch.types.map((pokemontypes) => pokemontypes.type.name)
    let pokemontype1 = pokemontypes[0];
    let pokemontype2 =pokemontypes[1];
    Card(pokemontype1,pokemontype2,pokemonNumber,pokemonName);
  }
}
  1. 在添加一个 div 后对附加的 div 进行排序。
    (我没有为这个写代码)

不过……

同时发出 898 个 API 请求并不是一个好主意,但等待它们按顺序加载也需要很长时间。所以在实践中应该使用返回请求的神奇宝贝列表的 API,或者只有在用户向下滚动时才应该扩展显示的 HTML 列表......但是对于训练当前的方式应该足够了。 ;)

Ti auguro un buon tempo per imparare JavaScript!

【讨论】:

  • 非常感谢! :D 如果代码写得不好,我很抱歉,正如我所说,我正在学习 Javascript,大约 3 个月前开始。我在这件事上被困了三天,所以你基本上是我的英雄。 :D
  • @AndreaCrinella 我们都是这样开始(并挣扎)的。而那些声称不撒谎的人。谢谢你的评论!像这样的小事激励我继续提供帮助。 :)
  • @AndreaCrinella 刚刚注意到 JAVASCRIPT.INFO 也有意大利语版本:it.javascript.info
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-09-18
  • 2022-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多