首页 > 语言 > JavaScript > 正文

redux-saga 初识和使用

2024-05-06 15:20:51
字体:
来源:转载
供稿:网友

redux-saga 是一个管理 Redux 应用异步操作的中间件,功能类似redux-thunk + async/await, 它通过创建 Sagas 将所有的异步操作逻辑存放在一个地方进行集中处理。

redux-saga 的 effects

redux-saga中的 Effects 是一个纯文本 JavaScript 对象,包含一些将被 saga middleware 执行的指令。这些指令所执行的操作包括如下三种:

    发起一个异步调用(如发一起一个 Ajax 请求) 发起其他的 action 从而更新 Store 调用其他的 Sagas

Effects 中包含的指令有很多,具体可以异步API 参考进行查阅

redux-saga 的特点

方便测试,例如:

assert.deepEqual(iterator.next().value, call(Api.fetch, '/products'))
    action 可以保持其纯净性,异步操作集中在 saga 中进行处理 watch/worker(监听->执行) 的工作形式 被实现为 generator 对含有复杂异步逻辑的应用场景支持良好 更细粒度地实现异步逻辑,从而使流程更加清晰明了,遇到 bug 易于追踪和解决。 以同步的方式书写异步逻辑,更符合人的思维逻辑 从 redux-thunk 到 redux-saga

假如现在有一个场景:用户在登录的时候需要验证用户的 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 }); }}            
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选