redux-saga 简介

redux-saga 是 redux 一个中间件,用于解决异步问题。

sagas的3种类型

root saga 立即启动的所有sagas的唯一入口

const sagaMiddleware = createSagaMiddleware();
const middlewares = [sagaMiddleware];

const store = createStore(appReducer, applyMiddleware(...middlewares));
sagaMiddleware.run(rootSaga);

watcher saga

监听被dispatch的actions,当接收到action或者知道其被触发时,调用worker saga执行任务

export default () => (function* () {

  // 在这里面进行effect 处理 (副作用的处理 一般是指异步请求)
  const task = yield takeEvery(loginAction.TRIGGER, authorize);
  // 监听两个type 一个是主动退出,一个是登录出错
  const action = yield take([loginAction.LOG_OUT, loginAction.FAILURE]);

  // 就可以手动去取消本次请求
  if( action.type === loginAction.LOG_OUT) yield cancel(task);

});

worker saga

执行具体的逻辑处理,如进行异步请求,处理返回结果等

const result =  yield call(loginUtils.saveLoginState, token)

简单理解 'redux-saga/effects' 中的几个关键字:fork,call, put,takeEvery,takeLatest,all

1、fork 创建一个新的进程或者线程,并发发送请求。同步执行

function* user() {
  yield takeEvery('FETCH_REQUEST', fetch_user); // 监听 FETCH_REQUEST action
}

// 并发发送请求
function* fetch_user() {
  const [users, todos] = [
    yield fork(fetchResource, 'https://jsonplaceholder.typicode.com/users'),
    yield fork(fetchResource, 'https://jsonplaceholder.typicode.com/todos')
  ]
}


function* fetchResource(resource) {
  const data = yield call(axios.get, resource);
  
  // 获取 call 数据,触发成功后的 action
  yield put({ type: 'FETCH_SUCESS', uu: data });
  
}

2、call 发送 api 请求 异步执行

 yield call(loginUtils, token)

3、all 跟 fork 一样,同时并发多个 action,没有顺序。 同步执行

yield all([
      fork(user()),
])

4、put 发送对应的 dispatch,触发对应的 action

yield put({ type:'login',data: {} })

5、select 用户获取store中的state的数据

put方法与redux中的dispatch相对应,同样的如果我们想在中间件中获取state,那么需要使用select。select方法对应的是redux中的getState,用户获取store中的state,使用方法:

const state= yield select();

6、take 是用来监听action,返回的是监听到的action对象 暂停Generator,

匹配的action被发起时,恢复执行。take结合fork,可以实现takeEvery和takeLatest的效果

const action = yield take('login');

7、takeEvery 监听对应的 action 每一次 dispatch 都会触发;

例如:点击一个新增的按钮,2s 后触发新增动作,在2s内不断点击按钮,这时候,每一次点击,都是有效的。

yield takeEvery('FETCH_USER', fetch_user);

8、takeLatest 监听对应的 action 只会触发最后一次 dispatch;

例如:点击一个新增的按钮,2s 后触发新增动作,在2s内不断点击按钮,这时候,只有最后一次点击是有效的。

yield takeLatest('FETCH_USER', fetch_user);

9、cancel 指示 middleware 取消之前的 fork 任务,cancel 是一个无阻塞 Effect。

race 竞速执行多个任务

原文地址:https://www.cnblogs.com/boyGdm/p/14140997.html