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

Redux Toolkit中await axios始终返回pending action问题排查

Redux Toolkit createAsyncThunk 数据返回异常排查

问题描述

我正从Ducks模式迁移到Redux Toolkit,目前遇到以下问题:

  • 使用await axios时始终返回pending action;
  • 移除await后API调用看似“正常”,但返回undefined;
  • 修改代码后能得到fulfilled action,但数据仍为undefined。

第一段代码

'movies/searchByTitle',
async (values, thunkAPI) => {
  const API_KEY = '';
  try {
    let {movieTitle} = values;
    let page = 1;
    
    let movies = await axios
      .get(
        `//api.themoviedb.org/3/search/movie?query=${movieTitle}&api_key=${API_KEY}&include_adult=false&page=${page}`,
      )
      .then(response => {
        console.log('results: ', response);
        return response.data;
      })
      .catch(error => {
        const message =
          (error.response &&
            error.response.data &&
            error.response.data.message) ||
          error.message ||
          error.toString();
        console.log(message);
        thunkAPI.rejectWithValue(error);
      });
    return movies;
  } catch (error) {
    const message =
      (error.response &&
        error.response.data &&
        error.response.data.message) ||
      error.message ||
      error.toString();
    console.log(message);
    return thunkAPI.rejectWithValue(message);
  }
},
);

修改后的代码

const API_KEY = '';

const fetchMoviesByTitle = async (title, page) => {
  const url = `https://api.themoviedb.org/3/search/movie?query=${title}&api_key=${API_KEY}&include_adult=false&page=${page}`;
  const {data} = axios.get(url);
  return await data;
};

export const searchByTitle = createAsyncThunk(
  'movies/searchByTitle',
  async (values, thunkAPI) => {
    let {movieTitle} = values;
    let page = 1;

    let data = await fetchMoviesByTitle(movieTitle, page)
      .then(results => {
        return results;
      })
      .catch(err => {
        return thunkAPI.rejectWithValue(err.message);
      });
    console.log(data);
    return data;
  },
);

错误分析与修复方案

核心错误点

  1. 修改后代码的致命错误
    fetchMoviesByTitle函数中,axios.get(url)返回的是一个Promise对象,直接解构{data}是从Promise本身上取data属性(而非等待Promise resolve后的响应对象),因此data的值是undefined,后续await data等价于等待一个undefined,最终返回结果必然是undefined。

  2. 两段代码的共同问题
    混用async/await和.then/.catch语法,导致Promise状态处理逻辑混乱:

    • 第一段代码中,.catch块调用thunkAPI.rejectWithValue但未return该值,使得catch块返回undefined,外层await得到的结果是undefined,且错误不会触发外层try/catch,最终thunk以fulfilled状态返回空数据;
    • 修改后的代码中,.then/.catch和await混用,进一步加剧了逻辑模糊。

正确写法

方案1:修复fetchMoviesByTitle并统一使用async/await

const API_KEY = '';

const fetchMoviesByTitle = async (title, page) => {
  const url = `https://api.themoviedb.org/3/search/movie?query=${title}&api_key=${API_KEY}&include_adult=false&page=${page}`;
  // 等待axios请求完成,获取响应对象
  const response = await axios.get(url);
  return response.data;
};

export const searchByTitle = createAsyncThunk(
  'movies/searchByTitle',
  async (values, thunkAPI) => {
    const { movieTitle } = values;
    const page = 1;
    try {
      const data = await fetchMoviesByTitle(movieTitle, page);
      console.log(data);
      return data;
    } catch (err) {
      return thunkAPI.rejectWithValue(err.message);
    }
  },
);

方案2:直接修复第一段代码(移除.then/.catch)

export const searchByTitle = createAsyncThunk(
  'movies/searchByTitle',
  async (values, thunkAPI) => {
    const API_KEY = '';
    try {
      const { movieTitle } = values;
      const page = 1;
      const response = await axios.get(
        `//api.themoviedb.org/3/search/movie?query=${movieTitle}&api_key=${API_KEY}&include_adult=false&page=${page}`,
      );
      console.log('results: ', response);
      return response.data;
    } catch (error) {
      const message =
        (error.response && error.response.data && error.response.data.message) ||
        error.message ||
        error.toString();
      console.log(message);
      return thunkAPI.rejectWithValue(message);
    }
  },
);

内容的提问来源于stack exchange,提问作者Asinox

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 20:26:01