当前位置: 代码迷 >> 综合 >> redux-saga学习笔记
  详细解决方案

redux-saga学习笔记

热度:81   发布时间:2023-12-03 09:34:41.0

redux-saga是什么?

在redux的学习中,我们知道,redux中的reducer函数一定是一个纯函数,即该函数不随全局改变,也不改变全局状态。然后当redux需要处理一些带有副作用的异步任务时,redux采用中间件改造 dispatch ,从而诞生了一批通过构造满足特殊 pattern 条件的 action 来解决副作用的问题。
而redux-saga是另一种非常强大处理副作用的工具。它提供了对异步流程更细粒度的控制,对每个异步流程他可以实现暂停、停止、启动三种状态。此外redux-saga利用了generator,对每个saga,其测试方式可以非常简单。更重要的是其异步处理逻辑放在了saga中,我们可以监听action触发,然后产生副作用。action依然是普通的redux action,不破坏redux对action的定义。
?

从redux中间件接口说起

虽然redux-saga是利用了generator生成器来实现一步方法的处理,但是原理上它和redux-thuk一样借用了redux的中间件接口来改造dispatch函数。所以先解释redux的中间件接口。redux的核心是控制和管理所有的数据输入输出,因此有了dispatch,由于dispatch是一个很纯的纯函数,就是单纯的派发action来更改数据,其功能简单且固定。而如果这时候需要对所有action统一添加记录日志的功能,那么最简单的就是在每个dispatch调用前添加一个日志输出代码,如下

console.log('dispatching', action);
dispatch(action)

如果此时程序中有很多的dispatch,我们就需要添加很多的重复代码,虽然编辑器提供批量替换,但这无疑是产生了很多样板代码。因为所有的需求都是和dispatch息息相关,我们只需要更改dispatch函数,把dispatch进行一层封装,然后将日志记录放进去就好了。如下:

let next = store.dispatch
store.dispatch = function dispatchAndLog(action) {
    console.log('dispatching', action)next(action)
}

而Redux把这个封装的入口写成了一个函数,就叫applyMiddleware。因此applyMiddleware的功能就是:改造dispatch函数,产生真假dispatch,而中间件就是运行在假真(dispatchAndLog假和next真)之间的代码。一个一个精简版的applyMiddleware如下:

const applyMiddleware = function(middleware){
    let next = store.dispatch;store.dispatch = middleware(store)(next);
}
applyMiddleware(dispatchAndLog) 

因此我们知道redux的中间件接口就是提供了一个可以串联融合封装dispatch的接口。
?

redux-saga的使用方法

有了redux的前置知识后我们就比较好理解redux-saga的使用了,下述是一个redux-saga的典型运用方法

function* del() {
    while(1){
    console.log("监听del type...");yield take('del');console.log("转发aciton");yield put({
    type:'asynDel'});}
}const sagaMiddleware=createSagaMiddleware();
const store = createStore((state = 0, action) => {
    switch (action.type) {
    case 'add': {
    console.log(state+1);return state+1;}case 'asynDel': {
    console.log(state-1);return state-1;}default: return state;}},applyMiddleware(sagaMiddleware)
);
sagaMiddleware.run(del);
store.dispatch({
    type: "add"});
store.dispatch({
    type: "del"});
store.dispatch({
    type: "del"});
store.dispatch({
    type: "add"});

如上图所示,redux首先通过createStore创建了一个store容器,同时通过applyMiddleware接口来加载由createSagaMiddleware创建的sagaMiddleware中间件,然后再中间件中sagaMiddleware.run(del)运行del生成器函数,在生成器函数中通过take函数可以监听action.type为del的action,并给出响应,监听到take后才会继续往下运行。上述代码的运行结果如下:

监听del type...
state+1
转发aciton
state-1
监听del type...
监听到del action
转发aciton
state-1
监听del type...
state+1
0

redux-saga副作用函数

为了更好的处理异步函数,配合生成器使用,redux-saga定义了一套副作用函数辅助用户使用,其中常用的函数包括了take、call、put、select、take Every等,介绍如下:

  • take:可以监听到UI传给redux Store的action,监听到后会立刻返回action
  • call:异步调用请求,用法 yeild call(fn,…args),返回描述对象
  • put:功能等同于redux中的dispatch函数,通过yeild put(action)发出后该action会立刻被reduce检测到。
  • select:等同于getState(),const state = yeild select();
  • takeEvery:yield takeEvery(‘login’,loginFunc)监听到login后就执行