为什么 Redux Saga yield 调用 return 一个函数,而不是数据?
Why Redux Saga yield call return a function, not data?
我正在尝试练习 redux saga,
我有一个问题不是 return 来自 async await
的数据。
使用以下代码:
/src/sagas/todos/index.js
export function* fetchTodosSaga() {
console.log('Ready to fetch Todos ...');
try {
const _todos = yield call(fetchTodos);
console.log(_todos); // Not a Result Data, It is a function
yield put({
type: "FETCH_TODOS_FULFILLED",
payload: {
todos: _todos
}
});
} catch (e) {
yield put({
type: "USER_FETCH_FAILED",
message: e.message
});
}
return 'Hello';
}
/src/actions/sagas/todos.js
export const fetchTodos = (params) => async (dispatch) => {
try {
const getTodosResponse = await todosAPI.getTodos(params);
console.log(getTodosResponse.data); // It is a CORRECT data
dispatch(fetchTodosAction(getTodosResponse.data));
return Promise.resolve(getTodosResponse.data);
} catch (error) {
return Promise.reject(error);
}
}
/src/services/api/todos/index.js
export default {
async getTodos() {
try {
return await axios.get(`${ baseUrl }/${ routes.todos }`);
} catch (error) {
return Promise.reject(error);
}
}
}
以及来自 chrome 检查员的控制台结果
ƒ (_x) {
return _ref.apply(this, arguments);
}
我该如何解决这个问题?
来自文档 call(fn, ...args):
fn: Function
- A Generator function, or normal function which either returns a Promise as result, or any other value.
但是你传递了一个 thunk 给 call
。 thunk returns 是一个函数,而不是一个 promise 或一个非函数值。这就是为什么 _todos
是一个函数。
当你使用redux-saga
时,你不需要使用redux-thunk
。您应该将 API 调用函数 todosAPI.getTodos
传递给 call
效果器。
例如
import { runSaga } from 'redux-saga';
import { call, put } from 'redux-saga/effects';
const todosAPI = {
async getTodos() {
return { data: ['a', 'b', 'c'] };
},
};
export function* fetchTodosSaga() {
try {
const _todos = yield call(todosAPI.getTodos);
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';
}
(function test() {
let dispatched = [];
runSaga({ dispatch: (action) => dispatched.push(action), getState: () => {} }, fetchTodosSaga);
})();
输出:
{ data: [ 'a', 'b', 'c' ] }
我正在尝试练习 redux saga,
我有一个问题不是 return 来自 async await
的数据。
使用以下代码:
/src/sagas/todos/index.js
export function* fetchTodosSaga() {
console.log('Ready to fetch Todos ...');
try {
const _todos = yield call(fetchTodos);
console.log(_todos); // Not a Result Data, It is a function
yield put({
type: "FETCH_TODOS_FULFILLED",
payload: {
todos: _todos
}
});
} catch (e) {
yield put({
type: "USER_FETCH_FAILED",
message: e.message
});
}
return 'Hello';
}
/src/actions/sagas/todos.js
export const fetchTodos = (params) => async (dispatch) => {
try {
const getTodosResponse = await todosAPI.getTodos(params);
console.log(getTodosResponse.data); // It is a CORRECT data
dispatch(fetchTodosAction(getTodosResponse.data));
return Promise.resolve(getTodosResponse.data);
} catch (error) {
return Promise.reject(error);
}
}
/src/services/api/todos/index.js
export default {
async getTodos() {
try {
return await axios.get(`${ baseUrl }/${ routes.todos }`);
} catch (error) {
return Promise.reject(error);
}
}
}
以及来自 chrome 检查员的控制台结果
ƒ (_x) {
return _ref.apply(this, arguments);
}
我该如何解决这个问题?
来自文档 call(fn, ...args):
fn: Function
- A Generator function, or normal function which either returns a Promise as result, or any other value.
但是你传递了一个 thunk 给 call
。 thunk returns 是一个函数,而不是一个 promise 或一个非函数值。这就是为什么 _todos
是一个函数。
当你使用redux-saga
时,你不需要使用redux-thunk
。您应该将 API 调用函数 todosAPI.getTodos
传递给 call
效果器。
例如
import { runSaga } from 'redux-saga';
import { call, put } from 'redux-saga/effects';
const todosAPI = {
async getTodos() {
return { data: ['a', 'b', 'c'] };
},
};
export function* fetchTodosSaga() {
try {
const _todos = yield call(todosAPI.getTodos);
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';
}
(function test() {
let dispatched = [];
runSaga({ dispatch: (action) => dispatched.push(action), getState: () => {} }, fetchTodosSaga);
})();
输出:
{ data: [ 'a', 'b', 'c' ] }