【源碼系列】redux-chunk、redux-promise 源碼分析

源碼系列react

上一篇文章裏,action 都是同步的,也就是說 dispatch(action),通過中間件,更新獲得 state 是同步的。git

下面介紹幾種 action 是異步執行的。github

redux-thunk

redux-chunk 是 redux 的一箇中間件 middleware,核心是建立一個異步的 action。redux

具體是怎麼實現的呢?首先了解一個概念,什麼是 thunk?promise

thunk

thunk 是一個函數,函數內有一個表達式,目的是爲了延時執行。react-router

let x = 1 + 2;
let foo = () => 1 + 2;
複製代碼

只有 foo() 執行時,才返回 3,那麼 foo 就是 chunk 函數。異步

redux-thunk 源碼不多,但又是經典,源碼以下:函數

function createThunkMiddleware(extraArgument) {
  return ({ dispatch, getState }) => next => action => {
    if (typeof action === 'function') {
      return action(dispatch, getState, extraArgument);
    }

    return next(action);
  };
}

const thunk = createThunkMiddleware();
export default thunk;

複製代碼

如源碼所示,redux-thunk 是個中間件,和其餘中間件區別就是,判斷 action 類型是一個函數時候,執行這個 action。而同步 action 執行返回是一個對象。源碼分析

例子:post

// dispatch(action) 時,通過中間件時,執行 next(action),更新獲得 state 是同步的。
const loading = text => ({
  type: 'LOADING',
  text
})

const cancelLoading = text => ({
  type: 'CANCEL_LOADING',
  text
})

// dispatch(action) 時,通過中間件時,執行 action(...args),更新獲得 state 是異步的。
const fetchPeople = (url, params) => {
  return ({dispatch, getState}) => {
    dispatch(loading('start loading'));
    fetch(url, params).then(delayPromise(3000)).then(data => {
      dispatch(cancelLoading('cancel loading'));
    });
  };
};
複製代碼

在線例子

redux-promise

redux-promise 也是中間件 middleware,原理和 redux-thunk 差很少,主要區別是 redux-promise 用到了 promise 異步。

源碼以下:

import isPromise from 'is-promise';
import { isFSA } from 'flux-standard-action';

export default function promiseMiddleware({ dispatch }) {
  return next => action => {
    if (!isFSA(action)) {
      return isPromise(action) ? action.then(dispatch) : next(action);
    }

    return isPromise(action.payload)
      ? action.payload
          .then(result => dispatch({ ...action, payload: result }))
          .catch(error => {
            dispatch({ ...action, payload: error, error: true });
            return Promise.reject(error);
          })
      : next(action);
  };
}
複製代碼

redux-promise 兼容了 FSA 標準(結果信息放在 payload 裏),實現過程就是判斷 action 或 action.payload 是否爲 promise 對象,是則執行 then().catch(),不然 next(action)

交流

下面是博客地址,以爲不錯點個Star,謝謝~

github.com/hankzhuo/Bl…

相關文章
相關標籤/搜索