簡單粗暴實現redux的thunk和promise中間件

文章地址javascript

異步處理

咱們使用 redux 處理數據流時候, 一個比較使人頭疼的問題就是關於異步操做。Action 發出之後,過一段時間再執行 Reducer,這就是異步。在哪一個階段處理異步, Reducer 做爲一個純函數, 不適合承擔此類功能, 理論上也承擔不了, Action 存放一個對象, 做爲消息的載體本身更不能進行異步操做。想想就發現能夠在 dispatch 這個發送 Action 的方法上作文章。若是咱們能在異步操做的不一樣階段發送不一樣的 Action 咱們就能夠完成異步操做了。java

thunk or promise

改造 dispatch

基於咱們以前實現的簡單 redux, 對於它的 dispatch 函數進行處理。使它具備處理咱們異步邏輯的能力。react

有時候看源碼總能感受到做者對代碼邏輯處理的很優雅, 以及對於功能的可擴展性把握的很好,可是每每這些優美的代碼,理解起來須要不少其餘方面的知識基礎, 這也是不少人看源碼困難很大的緣由。咱們這裏對與 redux 中間件的處理在後續再去討論, 這裏咱們就以一種比較蠢的方法簡單粗暴的實現咱們想要的功能git

加入 Thunk 能力

...
    const dispatch1 = store.dispatch
    store.dispatch = arg => {
        if (typeof arg === 'function') return arg(store.dispatch, getState)
        dispatch1(arg)
    }
    ...

這裏邏輯異常簡單, 先把原來的 dispatch 函數存儲起來, 判斷 dispatch 傳入的參數類型, 若是參數類型爲 function 則執行改函數並返回, 傳入 storedispatchgetState 做爲參數, 使得 dispatch 具備處理函數參數的能力。github

加入處理 Promise 能力

其實上面的 thunk 咱們已經有了處理異步的能力, 可是每次咱們要本身去手動觸發三個 action, 工做量仍是很大的。如今 ajax 不少都會包裝爲 promise 對象, 所以咱們能夠對與 dispatch 增長一層判斷, 使得它具備處理具備 promise 屬性的 action 的能力。ajax

...
    const dispatch2 = store.dispatch
    
    store.dispatch = action => {
        if (isPromise(action.payload)) {
            const { type, payload, params } = action
            dispatch2({
                type: `${type}_PENDDING`,
                params
            })
            payload.then(
                resolve => {
                    dispatch2({
                        type: `${type}_SUCCESS`,
                        content: resolve,
                        params
                    })
                },
                reject => {
                    dispatch2({
                        type: `${type}_ERROR`,
                        content: reject,
                        params
                    })
                }
            )
        } else {
            dispatch2(action)
        }
    }
    ...

咱們規定 action 要把 promise 對象放入 payload 屬性中。當接收到 payload 屬性爲 promise 對象的 action 時候, 咱們這裏硬編碼直接觸發該 type_PENDDING 事件。等到該 promise 狀態改變後, 咱們根據它成功與否分別觸發 _SUCCESS_ERROR 事件, 這樣咱們就能夠把異步邏輯包裝爲 promise 對象放在 action 中, 而後咱們在 reducer 中分別處理這幾種類型的事件便可。redux

測試和思考

咱們如今能夠在項目(reacts-ggsddu)中分別去 dispatch 一個函數和一個帶有 promise 對象的 action 能夠看到分別的請求效果。 一個簡易的異步處理方法已經實現了。promise

可是反觀對 dispatch 的改造沒有什麼統一性, 代碼很難維護和擴展, redux 是能夠配置中間件來擴展配置的。咱們後面再去研究。異步

相關文章
相關標籤/搜索