redux-saga 是一个管理 Redux 应用异步操作的中间件,功能类似redux-thunk + async/await, 它通过创建 Sagas 将所有的异步操作逻辑存放在一个地方进行集中处理。
redux-saga 的 effects
redux-saga中的 Effects 是一个纯文本 JavaScript 对象,包含一些将被 saga middleware 执行的指令。这些指令所执行的操作包括如下三种:
Effects 中包含的指令有很多,具体可以异步API 参考进行查阅
redux-saga 的特点
方便测试,例如:
assert.deepEqual(iterator.next().value, call(Api.fetch, '/products'))
假如现在有一个场景:用户在登录的时候需要验证用户的 username 和 password 是否符合要求。
使用 redux-thunk 实现
获取用户数据的逻辑(user.js):
// user.jsimport request from 'axios';// define constants// define initial state// export default reducerexport const loadUserData = (uid) => async (dispatch) => { try { dispatch({ type: USERDATA_REQUEST }); let { data } = await request.get(`/users/${uid}`); dispatch({ type: USERDATA_SUCCESS, data }); } catch(error) { dispatch({ type: USERDATA_ERROR, error }); }}
验证登录的逻辑(login.js):
import request from 'axios';import { loadUserData } from './user';export const login = (user, pass) => async (dispatch) => { try { dispatch({ type: LOGIN_REQUEST }); let { data } = await request.post('/login', { user, pass }); await dispatch(loadUserData(data.uid)); dispatch({ type: LOGIN_SUCCESS, data }); } catch(error) { dispatch({ type: LOGIN_ERROR, error }); }}
redux-saga
异步逻辑可以全部写进 saga.js 中:
export function* loginSaga() { while(true) { const { user, pass } = yield take(LOGIN_REQUEST) //等待 Store 上指定的 action LOGIN_REQUEST try { let { data } = yield call(loginRequest, { user, pass }); //阻塞,请求后台数据 yield fork(loadUserData, data.uid); //非阻塞执行loadUserData yield put({ type: LOGIN_SUCCESS, data }); //发起一个action,类似于dispatch } catch(error) { yield put({ type: LOGIN_ERROR, error }); } }}export function* loadUserData(uid) { try { yield put({ type: USERDATA_REQUEST }); let { data } = yield call(userRequest, `/users/${uid}`); yield put({ type: USERDATA_SUCCESS, data }); } catch(error) { yield put({ type: USERDATA_ERROR, error }); }}
新闻热点
疑难解答
图片精选