使用redux-thunk实现异步操作的中止

前端开发中常常会有这样的需求:设计一个select组件,每做一次选择就用ajax异步加载数据到指定页面。

实现这个需求并不困难,但是仅仅是这样做,难免会出现一些不太理想的体验:如果用户迅速的切换选项,那么返回的结果不一定是用户最后选择的那个结果。

因为请求是异步的,而请求发出到获得响应的过程时间是不可估的,用户很可能临时改变主意或等不及了而去发出一个新的请求。而页面最终呈现的结果是以最后到达的请求为准,因此具有一定的随机性。

这里使用redux的中间件thunk来改进action构造函数,达到‘中断‘用户最后一次之前的所有请求,只保留最后一次的效果。

关于中断和截流,月影有一篇关于函数式编程的PPT将的特别好,推荐大家去看一下,PPT中有嵌入JSBIN,大家可以直接在PPT中调试,《函数式编程,你必须知道的那些事》

而这里要提到的方法跟上述PPT中的都不一样,而且同样巧妙。
这里预先定义三个action创造函数:

  • fetchDataStarted
  • fetchDataSuccess
  • fetchDataFailed

顾名思义,分别返回数据发起和数据返回成功/失败的action,展示组件将根据传入的props的特定的状态渲染不同的内容(即‘数据加载中···‘,‘数据加载成功即其内容‘,‘数据加载失败及其原因‘)。那么现在就是要对每点击一次要派发的那个action对应的构造函数进行改写:

let nextSeqId = 0
export const fetchDataAction = (selectQuery) => {
    return (dispatch) {
        const apiUrl = 'data/select/${selectQuery}'
        const SeqId = ++nextSeqId
        const dispatchIfValid = action => {
            if(SeqId === nextSeqId){
                return dispatch(action)
            }
        }
        // 将状态改为开始发起请求
        dispatchIfValid(fetchDataStarted)
        //  发起请求
        fetch(apiUrl).then((response) => {
            if(response.status !== 200) {
                throw new Error('Fail to get Data with status'+response.status)
            }
            response.json().then((responseJson) => {
                dispatchIfValid(fetchDataSuccess(responseJson.data))
            }).catch( error => {
                dispatchIfValid(fetchDataFailed(error))
            })
        }).catch( error => {
            dispatchIfValid(fetchDataFailed(error))
        })
    }
}

这里定义了一个文件模块级的变量nextSeqId, 给所有的dispatch函数加了个包装函数,在执行前先判断请求发起时定义的seqId是否和当前的nextSeqId相等,如果相等才执行。虽然不能真正的‘中止‘请求,但是可以通过这种方法让一个API请求被忽略,达到同样的效果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值