博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
redux-promiseMiddleware的最佳实践
阅读量:5943 次
发布时间:2019-06-19

本文共 2231 字,大约阅读时间需要 7 分钟。

redux-promise-middleware 概述

我们之前关于中间件已经有做过讨论。关于 redux 的中间件,我们常用的一个用来处理异步的中间件为 redux-promise-middleware ,相比较 redux-promise 它保留了乐观更新的能力。在启用它之后,我们可以触发一个 payload 属性为 promise 对象的 action

const foo = () => ({  type: 'FOO',  payload: new Promise()})

中间件会立即触发一个 action,类型为我们声明的类型加上_PENDING(后缀我们可以自己配置).

{ type: 'FOO_PENDING' }

promise 对象的状态发生改变(resolved 或者 rejected ), 中间件会触发另外一个 action,并且带着 promise 的信息。

{  type: 'FOO_FULFILLED'  payload: { ... }}{  type: 'FOO_REJECTED'  payload: { ... }}

实现原理

关于它的, 其实比较容易理解, 就是判断了一下 actionpayload 属性

if (action.payload) {   if (!isPromise(action.payload) && !isPromise(action.payload.promise)) {     return next(action);   } } else {   return next(action); }

如果是 promise 对象则理解触发一个代表异步开始的 action

next({    type: [type, _PENDING].join(promiseTypeSeparator),    ...(data !== undefined ? { payload: data } : {}),    ...(meta !== undefined ? { meta } : {})});

然后等待这个 promise 对象状态改变后,根据成功与否触发不同的 action 并且携带这数据或者错误信息。结合作者的注释还是很容易看懂的。

实践分析

实践中,几乎每一个异步操作都有必要增加它乐观更新的能力,哪怕是一个简单的 button, 在操作中也会需要它有个 loading 状态,一方面给用户更好的体验,另一方面也防止了重复请求。

但是为了在 redux 中使用这个状态,不可避免的要针对每个异步 action 去声明很多变量去维护这个变量的值。如下

switch (action.type) {    case 'MY_ACTION_TYPE_PENDING':        return {...state, myActionLoading: true}    case 'MY_ACTION_TYPE_FULFILLED':        return {...state, xxx,  myActionLoading: false}    case 'MY_ACTION_TYPE_REJECTED':        return {...state, myActionLoading: false}}

我们写了很多这种重复的代码去做这种相同的事情, 既然我们每一个 actiontype 都是唯一的。为什么不做一个通用的方法去处理这种状态基的维护呢。

假如我们专门声明一个 reducer 去处理状态改变的事件。修改 redux-promise-middleware 处理过程,当有异步事件开始或者状态改变时,我们除了触发原来的事件外,也触发一个特殊事件的 action,它携带当前事件的 type状态 作为参数, 当接收到这个事件后我们把这个 reducer 对应的 type 的状态改为参数的的状态。这样我们就可以自动的更新每一个 action 目前的状态值了。

// reducer 类似如下// STATEMACHINE 指的是对应特殊事件的 `action's type`import { STATEMACHINE } from 'redux-promise-middleware'const uiStateStore = (state = {}, action) => {    switch (action.type) {        case STATEMACHINE: {            let { actionType, isFetching } = action            return {                ...state,                [actionType]: isFetching            }        }        default:            return state    }}...const mapStateToProps = state => ({    ...,    isLoading: state.uiState.MY_ACTION_TYPE})

效果如下

promise-middleware

可以在项目 运行 npm run async-2 体验。

转载地址:http://nyzxx.baihongyu.com/

你可能感兴趣的文章
go语言基础
查看>>
LINQ to SQL活学活用(1):这要打破旧观念
查看>>
Spring boot 嵌入的tomcat不能启动: Unregistering JMX-exposed beans on shutdown
查看>>
【Windows】字符串处理
查看>>
Spring(十八):Spring AOP(二):通知(前置、后置、返回、异常、环绕)
查看>>
CentOS使用chkconfig增加开机服务提示service xxx does not support chkconfig的问题解决
查看>>
微服务+:服务契约治理
查看>>
save
查看>>
Android DrawLayout + ListView 的使用(一)
查看>>
clear session on close of browser jsp
查看>>
asp.net mvc Post上传文件大小限制 (转载)
查看>>
关于吃掉物理的二次聚合无法实现的需要之旁门左道实现法
查看>>
mysql出现unblock with 'mysqladmin flush-hosts'
查看>>
oracle exp/imp命令详解
查看>>
开发安全的 API 所需要核对的清单
查看>>
Mycat源码中的单例模式
查看>>
WPF Dispatcher介绍
查看>>
fiddler展示serverIP方法
查看>>
C语言中的随意跳转
查看>>
WPF中如何将ListViewItem双击事件绑定到Command
查看>>