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

为什么Redux Saga中yield call返回函数而非实际请求数据?

问题根因

你定义的fetchTodos是一个Redux Thunk 风格的函数,调用后返回的是一个接收dispatch作为参数的异步函数,并不是直接返回请求结果。你用call(fetchTodos)执行时,拿到的就是它返回的这个匿名异步函数,自然不是你要的接口数据。

修复方案

方案1(推荐):直接在Saga中调用API,移除Thunk依赖

你已经在使用Redux Saga管理异步逻辑,不需要混用Thunk写法,直接调整Saga代码即可:
修改/src/sagas/todos/index.js:

// 先引入todosAPI
import todosAPI from '../../services/api/todos'

export function* fetchTodosSaga() {
    console.log('Ready to fetch Todos ...');
    try {
        // 直接call接口请求方法,拿到axios返回结果
        const getTodosResponse = yield call(todosAPI.getTodos);
        const _todos = getTodosResponse.data;
        console.log(_todos); // 此时就是正确的接口数据
        yield put({
            type: "FETCH_TODOS_FULFILLED",
            payload: {
                todos: _todos
            }
        });
    } catch (e) {
        yield put({ 
            type: "USER_FETCH_FAILED", 
            message: e.message 
        });
    }
    return 'Hello';
}

多余的fetchTodosThunk函数可以直接废弃,不需要再使用。

方案2:如果需要保留现有Thunk函数,调整调用方式

如果你的业务场景必须保留fetchTodos这个Thunk方法,可以手动执行它返回的异步函数,传入dispatch:

import { fetchTodos } from '../../actions/sagas/todos'

export function* fetchTodosSaga() {
    console.log('Ready to fetch Todos ...');
    try {
        // 先执行fetchTodos拿到返回的异步函数,再call这个异步函数,传入saga的put作为dispatch
        const fetchTodosThunk = fetchTodos();
        const _todos = yield call(fetchTodosThunk, put);
        console.log(_todos); // 此时得到正确数据
        // 注意:你的Thunk内部已经dispatch了fetchTodosAction,这里不需要再重复put成功事件,避免重复触发
    } catch (e) {
        yield put({ 
            type: "USER_FETCH_FAILED", 
            message: e.message 
        });
    }
    return 'Hello';
}

注意:该方案会导致你在Thunk和Saga中两次触发事件,冗余且不好维护,更推荐使用方案1。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 11:36:02