调用Jikan API获取动漫数据无控制台输出的原因排查
我希望调用接口
https://api.jikan.moe/v4/top/anime获取原始数据,从中提取有用字段生成数组。但运行以下Redux Toolkit代码后,控制台无任何输出也无报错,请帮忙排查原因:
const initialAnime = { anime: [], genresLoaded: false, genres: [], }; function createAnimeFromRawData(rawData, animeArray) { const data = rawData.data; data.forEach((animeData) => { const anime = { mal_id: animeData.mal_id, title: animeData.title, title_english: animeData.title_english, type: animeData.type, episodes: animeData.episodes, status: animeData.status, duration: animeData.duration, rating: animeData.rating, rank: animeData.rank, synopsis: animeData.synopsis, }; console.log(animeArray); animeArray.push(anime); }); } const RawdataAnime = async (api, genre, paging) => { const Animearray = []; for (let i = 1; Animearray.length < 60 && i < 10; i++) { const { data: { results }, } = await axios.get(`${api}`); createAnimeFromRawData(results, Animearray); } return Animearray; }; export const fetchAnime = createAsyncThunk( "myanimelist/topAnime", async (thunkAPI) => { const { myanimelist: { genres }, } = thunkAPI.getState(); return RawdataAnime(`https://api.jikan.moe/v4/top/anime`, genres, false); } ); const animeSlice = createSlice({ name: "Myanimelist", initialState: initialAnime, extraReducers: (builder) => { builder.addCase(getGenresAnime.fulfilled, (state, action) => { state.genres = action.payload; state.genresLoaded = true; }); builder.addCase(fetchAnime.fulfilled, (state, action) => { state.anime = action.payload; }); }, }); export const store = configureStore({ reducer: { netflix: netflixSlice.reducer, anime: animeSlice.reducer, }, });
核心问题排查
API响应结构解析错误
Jikan v4的/top/anime接口返回的直接是包含动漫数据的data数组,不存在results字段。代码中试图解构data: { results }会导致results为undefined,后续调用createAnimeFromRawData时传入无效值,自然无法生成数据。数据转换函数逻辑错误
即使API解析正确,调用createAnimeFromRawData(results, Animearray)时,若results是接口返回的data数组,函数内又去取rawData.data(把数组当成对象取属性),结果为undefined,forEach不会执行,无数据被添加到数组。未处理异步请求失败状态
fetchAnime异步thunk未配置rejected状态处理,即使API请求失败(如限流、网络问题),控制台也不会输出错误信息,无法定位问题。未定义的
getGenresAnimethunkextraReducers中添加了getGenresAnime.fulfilled的处理,但代码未定义该异步thunk,可能导致slice初始化隐性错误,影响整体流程。state路径错误
fetchAnime中从state取myanimelist: { genres },但store的reducer键是anime,正确路径应为anime: { genres },否则取不到genres值(虽不影响当前数据获取,但属于逻辑错误)。分页参数缺失
循环中尝试分页获取数据,但未在API URL中添加page参数(Jikan v4分页参数为page),导致每次请求都是第一页数据,重复获取且无法达到60条的目标。
修正后的代码示例
import { createAsyncThunk, createSlice, configureStore } from '@reduxjs/toolkit'; import axios from 'axios'; const initialAnime = { anime: [], genresLoaded: false, genres: [], }; // 修正数据转换:直接接收接口返回的data数组 function createAnimeFromRawData(rawDataArray, animeArray) { rawDataArray.forEach((animeData) => { const anime = { mal_id: animeData.mal_id, title: animeData.title, title_english: animeData.title_english, type: animeData.type, episodes: animeData.episodes, status: animeData.status, duration: animeData.duration, rating: animeData.rating, rank: animeData.rank, synopsis: animeData.synopsis, }; animeArray.push(anime); }); } // 修正API请求:添加分页参数,处理错误 const RawdataAnime = async (api) => { const animeArray = []; for (let i = 1; animeArray.length < 60 && i < 10; i++) { try { // 添加page参数实现分页 const { data } = await axios.get(`${api}?page=${i}`); createAnimeFromRawData(data, animeArray); console.log(`第${i}页加载完成,当前总数:${animeArray.length}`); } catch (err) { console.error(`第${i}页加载失败:`, err.message); break; } } return animeArray; }; export const fetchAnime = createAsyncThunk( "myanimelist/topAnime", async (_, thunkAPI) => { // 修正state路径:从anime reducer取genres const { anime: { genres } } = thunkAPI.getState(); return RawdataAnime(`https://api.jikan.moe/v4/top/anime`, genres); } ); const animeSlice = createSlice({ name: "Myanimelist", initialState: initialAnime, extraReducers: (builder) => { // 移除未定义的getGenresAnime.fulfilled(或补充定义该thunk) builder.addCase(fetchAnime.pending, () => { console.log('正在加载动漫数据...'); }); builder.addCase(fetchAnime.fulfilled, (state, action) => { state.anime = action.payload; console.log('数据加载完成:', action.payload.length, '条'); }); builder.addCase(fetchAnime.rejected, (_, action) => { console.error('数据加载失败:', action.error.message); }); }, }); export const store = configureStore({ reducer: { // 若netflixSlice未定义,需注释或补充实现 // netflix: netflixSlice.reducer, anime: animeSlice.reducer, }, });
内容的提问来源于stack exchange,提问作者Fam fas

