You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript Fetch如何筛选PokeAPI火/水/草属性宝可梦

核心结论

完全可以在拉取全量宝可梦详情前完成筛选,PokéAPI原生提供按属性维度的聚合接口,根本不需要逐个拉取所有宝可梦的详情再过滤。

原实现的效率问题

你当前的代码存在两个明显的性能损耗点:

  • 逻辑上先拉取150只宝可梦的索引列表,再逐个发请求拉取每只的详情,总共要产生151次接口请求,其中不属于火/水/草属性的宝可梦详情请求全是冗余的
  • 写法上用for...of搭配await串行发送请求,整体加载速度非常慢

优化实现方案

PokéAPI自带属性分类接口,火、水、草三个目标属性对应的接口路径分别为:

  • 火属性:/type/fire
  • 水属性:/type/water
  • 草属性:/type/grass

这三个接口返回数据的pokemon字段,直接列出了所有归属该属性的宝可梦,且每个条目自带slot字段,直接标记当前属性属于宝可梦的第几个属性位,完全满足你检查slot1、slot2属性的需求。
你只需要并发请求这三个接口,合并结果后去重,再按你需要的ID范围(比如前150号关都宝可梦)过滤即可,全程仅需3次接口请求,不需要拉取任何单只宝可梦的详情就能拿到符合要求的宝可梦列表。如果你确实需要宝可梦的完整详情,也只需要对筛选后的小部分结果发详情请求,请求量会从150次降到几十次甚至更少。

参考代码

const TARGET_TYPES = ['fire', 'water', 'grass']
const MAX_POKEMON_ID = 150 // 限定取前150号全国图鉴宝可梦
const TYPE_API_BASE = 'https://pokeapi.co/api/v2/type/'

async function getFilteredPokemons() {
  try {
    // 并发拉取三个属性的关联宝可梦列表
    const typeResults = await Promise.all(
      TARGET_TYPES.map(type => fetch(`${TYPE_API_BASE}${type}`).then(res => res.json()))
    )

    // 合并结果、去重、过滤ID范围
    const pokemonCache = new Map()
    typeResults.forEach(typeData => {
      typeData.pokemon.forEach(relation => {
        // 只保留slot1、slot2的属性关联
        if (relation.slot > 2) return
        const pokemonUrl = relation.pokemon.url
        // 从URL中提取宝可梦全国图鉴ID
        const pokemonId = Number(pokemonUrl.split('/').filter(Boolean).pop())
        // 过滤超出ID范围的宝可梦,同时去重
        if (pokemonId <= MAX_POKEMON_ID && !pokemonCache.has(pokemonId)) {
          pokemonCache.set(pokemonId, {
            id: pokemonId,
            name: relation.pokemon.name,
            url: pokemonUrl
          })
        }
      })
    })

    // 如果需要完整详情,取消下面这段注释即可,只会请求筛选后的宝可梦
    // const finalList = await Promise.all(
    //   Array.from(pokemonCache.values()).map(pokemon => 
    //     fetch(pokemon.url).then(res => res.json())
    //   )
    // )

    // 不需要详情直接用缓存的列表即可
    const finalList = Array.from(pokemonCache.values())
    console.log(finalList)
    return finalList
  } catch (err) {
    console.error('拉取数据失败:', err)
  }
}

getFilteredPokemons()

补充提示:如果你只需要宝可梦的名称、详情页地址这类基础信息,直接用三个属性接口返回的结果即可,不需要额外发任何详情请求,加载速度比你原来的实现快几十倍。


内容的提问来源于stack exchange,提问作者Alejandro Arias Aguilar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 16:27:21