资讯专栏INFORMATION COLUMN

Redux技术架构简介(二)-- 异步实现

wuaiqiu / 2793人阅读

摘要:异步实现设计需要增加三种通知异步请求发起的异步请求成功的异步请求失败的示例代码如下返回参数完全可以自定义。这种分别在请求开始前,请求成功后,请求失败后发送。表示数据的有效性,他的作用是在异步请求发送失败后,告诉当前的数据是过时的数据。

说明:对Redux不了解的同学可先看看这篇文章Redux技术架构简介(一)

前言

这里说的Redux异步实现,是专指Redux中的异步Action实现,而不是指应用的异步实现,因为Redux本身只支持同步action,即发送action,state立即更新;那如果我在发送一个action后,需要state过一段时间再更新呢?按正常的思路redux是无法处理这种情况的,下面就来看看异步Action是如何实现的吧!

需要提的一点是,其实完全可以将异步逻辑写在View中,然后在回调函数中发送action。但是如果你要配合react一起使用,这样做就违背了react-redux的设计思想,即UI与逻辑的分离(具体的实现可以在下一篇文章中看到),而且当存在多个异步请求时也很难将异步逻辑抽象出来,所以异步逻辑应该由Redux架构实现,这样也就必须实现发送异步action了
1. 中间件(Middleware)

为了解决上面提到的问题,我们需要引入中间件的概念。

(1)时机

中间件执行的时机是在action发起之后,reducer执行之前。


即在dispatch一个action之后,经过一系列的中间件处理过程,再进行reducer。

(2)原理

本质上,中间件就是对dispatch函数的改造。当执行dispatch(action)时,会先调用中间件,进行一些内部逻辑处理,如:添加日志等,之后再执行dispatch。如果要支持中间件的链式调用,必须再返回一个dispatch。
下面是中间件的简单实现:

function logger(store) {
  // 这里的 next 必须指向前一个 middleware 返回的函数:
  const next = store.dispatch

  return function dispatchAndLog(action) {
    console.log("dispatching", action)
    let result = next(action)
    console.log("next state", store.getState())
    return result
  }
}
(3) 在Redux中应用中间件

可以使用Redux的API—applyMiddleware直接使用中间件,代码如下:

import {applyMiddleware,createStore} from "redux";
import {createLogger} from "redux-logger";//log中间件
import thunk from "redux-thunk";//将dispatch改造成可以接受函数作为参数的中间件
import indexPhotomainReducer from "../reducer/indexPhotomainReducer";

const logger = createLogger();
const store  = createStore(
        indexPhotomainReducer,
        applyMiddleware(thunk, logger)
);

由此可见,可以把applyMiddleware作为createStore的第二个参数传入,你所使用的中间件需要下载多带带npm包,然后按顺序传入applyMiddleware函数中(注:中间件有顺序要求,需要看下每个中间件的使用文档,logger一般要放在最后)。

2. Redux异步实现 (1) Action设计

需要增加三种action

通知异步请求发起的action

异步请求成功的action

异步请求失败的action

示例代码如下:

export const requestPostsAction = () => {
 return {
     type: REQUEST_POSTS
 };
}

export const receivePostsSuccessAction = (data) => {
 return {
     type: RECEIVE_POSTS_SUCCESS,
     data
 };
}
export const receivePostsFailureAction = (error) => {
 return {
     type: RECEIVE_POSTS_FAILURE,
     error
 };
}

返回参数完全可以自定义。这3种action分别在请求开始前,请求成功后,请求失败后发送。
## (2) State设计
为了配合异步Action,可以在state树中增加2个属性:

isFetching:表示是否正在处理异步请求。

isValidate:表示数据的有效性,他的作用是在异步请求发送失败后,告诉View当前state的数据是过时的数据。

State属性可以凭自己喜好随意设计。设计好后可以这样编写reducer:

let sliderReducer = function (state = initialState, action) {
    switch(action.type){
        case photomainAction.RECEIVE_POSTS_SUCCESS:
               return Object.assign({}, state, {photoData,videoData,isFetching:false,isValidate:true});
        case photomainAction.RECEIVE_POSTS_FAILURE:
               return Object.assign({}, state, {isFetching:false,isValidate:false});
        case photomainAction.REQUEST_POSTS:
               return Object.assign({}, state, {isFetching:true,isValidate:false});
        default:
            return state;
    }
}
(3) redux-thunk中间件

当设计好action和state后,我们想要达到的效果是--可以像同步一样dispatch一个action,而不用考虑异步逻辑。
为了达到这种效果,首先面临的问题是,异步逻辑放在哪里?这里只有2个选择:action中或reducer中(store是不适合处理数据的)。由于reducer必须是一个纯函数,他不适合处理像异步请求这样存在不确定的输出的逻辑。最后只能放在action中处理了。
这时,为了处理异步请求,action创建函数需要返回一个带有异步请求逻辑的函数,而不是一个对象了。而dispatch只能接受对象,不能接受函数作为参数,这样就面临又一个问题:如何让dispatch接受函数?
接下来就是redux-thunk中间件发挥作用的时候了,他可以让dispatch接受一个函数(原理就是上一节讲的,他其实是改写了dispatch函数),最终异步的action可以这样实现:

//定义一个action creator – fetchPosts
export const fetchPosts = () => (dispatch, getState) => {
    dispatch(requestPostsAction());
    return window.fetch("/photo/initPage").then(response=>{
            if(response.ok){
                return response.json();
            }else{
                dispatch(receivePostsFailureAction("error"));
            }
        }).then(data => {
            if(data){
                dispatch(receivePostsSuccessAction(data));
            }else{
                dispatch(receivePostsFailureAction("error"));
            }
        });
}

这样就可以像同步一样发送action了,即:

dispatch(fetchPosts());

接下来只需静静等待view的更新就行了,这样就实现了整个Redux的异步流程。

本篇到此告一段落,下一篇介绍React与Redux整合技术。

参考

Redux 中文文档
Redux 入门教程-阮一峰

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/95078.html

相关文章

  • Redux技术架构简介

    摘要:是一个程序架构,源于提出的一种架构,然而,它不仅可以应用于,还可以应用于其他任何框架中。有以下职责维持应用的提供方法获取提供方法更新通过注册监听器通过返回的函数注销监听器。同时,的返回值实际上是一个函数可以解除监听。 Redux是一个程序架构,源于Flux(Facebook提出的一种架构),然而,它不仅可以应用于React,还可以应用于其他任何框架中。值得一提的是,Redux的源代码很...

    weizx 评论0 收藏0
  • 一些基于React、Vue、Node.js、MongoDB技术栈的实践项目

    摘要:利用中间件实现异步请求,实现两个用户角色实时通信。目前还未深入了解的一些概念。往后会写更多的前后台联通的项目。删除分组会连同组内的所有图片一起删除。算是对自己上次用写后台的一个强化,项目文章在这里。后来一直没动,前些日子才把后续的完善。 欢迎访问我的个人网站:http://www.neroht.com/ 刚学vue和react时,利用业余时间写的关于这两个框架的训练,都相对简单,有的...

    tangr206 评论0 收藏0
  • ELSE 技术周刊(2017.10.23期)

    摘要:为目前使用范围最广的网络保护协议。身处攻击目标周边的恶意人士能够利用密钥重装攻击,利用此类安全漏洞。本文和大家一起探讨下如何在三年内快速成长为一名技术专家。 业界动态 Vue 2.5 released Vue 2.5 正式发布,作者对于该版本的优化总结:更好的TypeScript 集成,更好的错误处理,更好的单文件功能组件支持以及更好的与环境无关的SSR WiFi爆惊天漏洞!KRACK...

    galaxy_robot 评论0 收藏0
  • React与Redux整合技术简介

    摘要:展示组件与容器组件的绑定库的基本开发思想是展示组件与容器组件相分离。技术上讲,容器组件就是使用从树中读取部分数据,并通过来把这些数据提供给要渲染的组件。 说明:阅读本篇文章需要对Redux有一定的了解,对Redux不了解的同学可先看看这篇文章Redux技术架构简介(一) 1. React中引入react-redux 为了让Redux和React更好的配合,Facebook专门开发了一个...

    idealcn 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<