My applyMiddleware of redux

 · 1 min read

After reading the Async Actions and Middleware chapters of redux tutorial, I implemented my own middleware thunk, you can see this demo.

In the example of offcial guide, it is considering the synchronous case so I just want to produce a applyMiddleware which could be applid both to sync and async function. I know they have already done that, but I just want to practice and make it my own way.

In order to apply to both sync and async situation, we need our middlewares returning a promise object, which, for sync functions, it is already resolved.

I used these techniques:

  1. arrow function
  2. currying
  3. deferred calculation
  4. reduce

I think you can easily understand these code with those knowledge I mentioned above. So I will pass explaination, haha…

    <div>
        <input type="text" id="msg" />
        <button onclick="submit()">submit</button>
        <button onclick="apply()">applyMiddleware</button>
        <p id="result"></p>
    </div>
var input = document.querySelector('#msg')
        var p = document.querySelector('#result')
        p.innerHTML = 'input some characters then submit'

        function submit() { store.dispatch(input.value) }

        function apply() { 
            store = applyMiddleware(store, proc1, proc2)
            p.innerHTML = 'applied! try again'
         }


        function createStore() {
            return {
                dispatch: str => p.innerHTML = 'dispatch: ' + str
            }
        }

        var store = createStore()

        const proc1 = next => str => Promise.resolve('proc1(' + str + ')').then(value => next(value))

        const proc2 = next => str => new Promise((resolve, reject) => {
            p.innerHTML = 'requesting... wait 2 seconds'
            setTimeout(() => {
                if (str.indexOf('yang') != -1) {
                    resolve('proc2(' + str + ')')
                } else {
                    reject('proc2_fault(' + str + ')')
                }
            }, 2000)
        }).then(value => next(value)).catch(reason => next(reason))


        function applyMiddleware(store, ...procs) {
            var handlers = procs.slice().reverse()
            var dispatch = str => handlers.reduce((result, handler) => handler(result), store.dispatch)(str)
            return Object.assign({}, store, {
                dispatch
            })
        }

LINKS:

Middleware