简单粗暴实现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 是能够配置中间件来扩展配置的。咱们后面再去研究。异步

相关文章
相关标签/搜索