从PokeAPI获取招式类型遇问题:索引访问返回单字符而非类型名
解决招式类型获取错误的问题
你之所以会遇到这个问题,是因为搞错了PokeAPI招式接口的返回结构:招式的类型数据不是存在data.type里,而是在data.types数组中,每个数组元素包含一个type对象,里面才是name字段。
问题分析
- 代码示例1里的
data.type.name是错误写法,实际应该访问data.types数组。如果你当时看到的是独立数组,大概率是误把data.types写成了data.type,导致返回了整个类型数组而非类型名称。 - 代码示例2里访问
typeName[0]得到单个字符,说明typeName其实是字符串(比如误打误撞拿到了某个字符串属性),所以索引访问会取字符串的第一个字符,而非数组元素。
修正后的代码
下面是正确获取招式类型并设置背景色的实现,同时用Promise.all并行处理请求,比嵌套forEach更高效:
const url = `https://pokeapi.co/api/v2/pokemon/1` fetch(url) .then(response => response.json()) .then(data => { // 提取所有招式的API地址 const movesUrl = data.moves.map(move => move.move.url); // 并行请求所有招式数据,返回包含招式名和类型的数组 return Promise.all( movesUrl.map(moveUrl => fetch(moveUrl) .then(res => res.json()) .then(moveData => { // 取第一个类型(大部分招式只有一个类型,双类型可遍历types数组) const typeName = moveData.types[0].type.name; return { moveName: moveData.name, typeName }; }) ) ); }) .then(movesWithTypes => { // 定义宝可梦类型对应的背景色映射 const typeColorMap = { normal: '#A8A878', fire: '#F08030', water: '#6890F0', grass: '#78C850', electric: '#F8D030', psychic: '#F85888', ice: '#98D8D8', dragon: '#7038F8', dark: '#705848', fairy: '#EE99AC', fighting: '#C03028', flying: '#A890F0', poison: '#A040A0', ground: '#E0C068', rock: '#B8A038', bug: '#A8B820', ghost: '#705898', steel: '#B8B8D0' }; // 遍历招式,创建元素并设置背景色 movesWithTypes.forEach(({ moveName, typeName }) => { const moveElement = document.createElement('div'); moveElement.textContent = moveName; // 用对应的颜色,默认灰色 moveElement.style.backgroundColor = typeColorMap[typeName] || '#CCCCCC'; // 添加一些样式让效果更明显 moveElement.style.padding = '8px 12px'; moveElement.style.margin = '4px'; moveElement.style.borderRadius = '4px'; moveElement.style.display = 'inline-block'; document.body.appendChild(moveElement); }); }) .catch(err => console.error('请求出错:', err));
关键说明
- 用
Promise.all替代嵌套forEach:既可以并行发起所有招式请求,提升性能,还能保证所有请求完成后再统一处理结果。 - 处理双类型招式:如果需要支持有两个类型的招式,可以遍历
moveData.types数组,给元素添加多个背景色或者用渐变。 - 类型颜色映射:你可以根据自己的设计需求调整
typeColorMap里的颜色值。
内容的提问来源于stack exchange,提问作者Pedro Rebello
相关产品推荐
相关产品推荐

