zoukankan      html  css  js  c++  java
  • reduxthunk 和 reduxsaga 的区别?

    redux-thunk 和 redux-saga 的区别?

     

    毋庸置疑,如果需要用到 side effect 异步操作,redux-thunk 和 redux-saga 绝对是目前两个最受欢迎的中间件插件。那么他们之间最主要的区别是什么?

     

    这就要首先说一说使用 redux 时异步操作出现的具体时机。

    如下如所示,当出发一个 action 会经过中间件 middlewares,这时所有的 side effect 操作,例如调用 api 获取数据等等都将在这里完成。然后再经由 reducer 更新 state,最后传递到 view 完成 MVC 的数据流循环。

    所有的调取数据都在 api 那部分完成

     

    redux-thunk 解决方案

     

    首先 thunk 来源自 think 的”过去式“ -- 作者非常特别的幽默感。主要意思就是声明一个函数来代替表达式,这样就可以将执行求值操作(evaluation)延迟到所需要的时刻。

    // calculation of 1 + 2 is immediate
    // x === 3
    let x = 1 + 2;
    
    // calculation of 1 + 2 is delayed
    // foo can be called later to perform the calculation
    // foo is a thunk!
    let foo = () => 1 + 2;
    

     

    注册插件很简单,大致代码如下

    // Note: this API requires redux@>=3.1.0
    const store = createStore(rootReducer, applyMiddleware(thunk));
    
    ReactDOM.render(
      <Provider store={store}>
        <Routes />
      </Provider>,
      document.getElementById('root')
    );

     

    Reducer 也非常简单,和原来一模一样

    export default (state = defaultState, action) => {
      switch (action.type) {
        case REMOTE_DATA_RECEIVED:
          return {
            ...state,
            data: action.data
          };
        default:
          return state;
      }
    };

     

    不同之处在于 action,普通的 action 大多长这样

    export function toggleTodo(index) {
      return { type: TOGGLE_TODO, index }
    }

     

    而 redux-thunk 的 action 可以是一 异步的 higher order function 高阶函数

    export const fetchData = args => async (dispatch, getState) => {
      const state = getState();
      const url = 'https://jsonplaceholder.typicode.com/users/' + args;
    
      try {
        const response = await fetch(url)
          .then(resp => {
            return resp;
          })
          .then(resp => resp.json());
    
        dispatch({
          type: REMOTE_DATA_RECEIVED,
          data: response
        });
      } catch (error) {
        console.log(error);
      }
    };

     

    其他的地方关于 view 等都是一样的操作。

     

    redux-saga 解决方案

     

    注册插件大家都很类似

    import { createStore, applyMiddleware } from 'redux';
    import createSagaMiddleware from 'redux-saga';
    import rootReducer from './root-reducer';
    import { watchFetchSaga } from './saga/fetchData.saga';
    
    const sagaMiddleware = createSagaMiddleware();
    const store = createStore(rootReducer, applyMiddleware(sagaMiddleware));
    sagaMiddleware.run(watchFetchSaga);
    
    ...

     

    但是 saga 使用的仍然是普通的 action

    // 这个 action 将由 saga 监听,并且出发 side effect 异步加载 api 操作
    export const fetchData = () => ({
      type:  "START_FETCH_DATA"
    });
    
    // 这个 action 将由 saga 发出
    export const fetchSuccess = data => ({
      type: "REMOTE_DATA_RECEIVED",
      payload: data
    });

     

    接下来就是注册 saga 相关 side effect 操作。下面的文件是 fetchData.saga.js

    import { takeLatest, put } from "redux-saga/effects";
    
    function* fetchDataSaga(action){
      try {
        const response = yield fetch(action.url);
        const data = yield response.json()
        yield put(fetchSuccess(data));
      } catch (error) {
        console.log(error);
      }
    }
    
    export default function* watchFetchSaga(){
      // saga 将监听此事件,takeLatest 表示仅仅只监听最新的此事件
      yield takeLatest("START_FETCH_DATA", fetchDataSaga)
    }
    

     

    总结

     

    可以看到 saga 自己基本上完全弄了一套 asyc 的事件监听机制。虽然好的一方面是将来可以扩展成 worker 相关的模块,甚至可以做到 multiple threads 同时执行,但代码量大大增加。如果只是普通的 application,用 redux-thunk 足够。

     

    redux-thunk 是 2015-7-13 发布的第一个版本,而 redux-saga 是 2015-12-2 发布的第一个版本。他们基本上都是在同一年被创造出来。

     

    下面是两者周下载量。

    redux-thunkredux-saga

     

    除了上面的数据我再来说说自己的使用感受。这两款插件我均正式使用过,而且都是用于商业软件开发。从我自己的使用体验来看 redux-thunk 更简单,和 redux 本身联系地更紧密。尤其是整个生态都向函数式编程靠拢的今天,redux-thunk 的高阶函数看上去更加契合这个闭环。

     

    如果有的选,我肯定选 redux-thunk。因为

    1)简单才是王道

    2)从名字本身上来看也更性感

     

    你会怎么选?欢迎留言告诉我你的想法。

  • 相关阅读:
    这仅仅是一份工作
    和老总之间的对话
    假设满足怎样的条件,就不去编程
    那都是别人的架构
    程序员狂想曲
    学点经济学知识(三)
    一起来看 HTML 5.2 中新的原生元素 <dialog>
    动态配置页面 之 组件系统
    初识JavaScript EventLoop
    webpack+vue-cli+ElementUI+vue-resource 前端开发
  • 原文地址:https://www.cnblogs.com/sexintercourse/p/15689873.html
Copyright © 2011-2022 走看看