在Redux中常要管理异步操作,目前社区流行的有Redux-Saga、Redux-thunk等。在管理复杂应用时,推荐使用Redux-Saga,它提供了用 generator 书写类同步代码的能力。

在讲解 ReduxSaga 前,先要说明一下 Redux Middleware 的概念。

Middleware

它提供的是位于 action 被发起之后,到达 reducer 之前的扩展点。

如果写过 Koa 或者 Express ,就会很容易理解 Middleware 的概念。

可以说,Middleware 是一种置于一个调用发起到被处理这段过程之间的函数。它可以对发起的调用进行处理,处理后直接返回,或者调用下一个中间件。

在Redux中,使用柯里化函数声明中间件,一个简单的例子如下:

/**
* 记录所有被发起的 action 以及产生的新的 state。
*/
const logger = store => next => action => {
console.group(action.type)
console.info('dispatching', action)
let result = next(action)
console.log('next state', store.getState())
console.groupEnd(action.type)
return result
}

然后需要将它应用到Redux上

import { createStore, combineReducers, applyMiddleware } from 'redux'

const todoApp = combineReducers(reducers)
const store = createStore(
todoApp,
// applyMiddleware() 告诉 createStore() 如何处理中间件
applyMiddleware(logger, crashReporter)
)

之后dispatch的每一个action都会触发log中间件。

更详细的用法在Redux文档里说明得很详细了,Redux-Middleware

使用Redux Saga

先定一个小目标,写一个异步增加的demo。

先来创建一个sagas.js文件,用来存放我们的sagas。

import { delay } from 'redux-saga'
import { put, takeEvery } from 'redux-saga/effects' export function* plusAsync() {
yield delay(1000)
yield put({ type: 'PLUS' })
} // 在dispatch到store并且匹配pattern的每一个action上派生一个saga
export function* watchPlusAsync() {
yield takeEvery('PLUS_ASYNC', incrementAsync)
}

在上篇例子的基础上,增加一个按钮,用来派发PLUS_ASYNC事件。

 <button onClick={dispatch({type: 'PLUS_ASYNC'}}>{"plusAsync"}</button>

在使用时,经常需要将多个sagas合并成一个。

import { all } from 'redux-saga/effects'

// ...

export default function* rootSaga() {
yield all([
watchPlusAsync()
])
}

最后,需要创建saga Middleware。并将中间件应用到redux上。

import { createStore, applyMiddleware } from "redux";

// ...

// 创建一个Store
const sagaMiddleware = createSagaMiddleware()
const store = createStore(
counter,
applyMiddleware(sagaMiddleware)
) // 运行sagas
sagaMiddleware.run(allSagas);

常用API说明

middleware.run(saga, ...args)

动态地运行 saga。只能 用于在 applyMiddleware 阶段 之后 执行 Saga。

takeEvery(pattern, saga, ...args)

在发起(dispatch)到 Store 并且匹配 pattern 的每一个 action 上派生一个 saga。

pattern用来匹配对应的TYPE,对应到指定的saga处理函数上。

args就是相当于指定给saga的参数数组,并且takeEvery会将action拼到最后一个参数上。

takeLatest(pattern, saga, ...args)

在发起到 Store 并且匹配 pattern 的每一个 action 上派生一个 saga。并自动取消之前所有已经启动但仍在执行中的 saga 任务。

这个函数可以说是takeEvery的防抖版本。

具体例子可以查看这里-redux_saga_example

put(action)

创建一个 Effect 描述信息,用来命令 middleware 向 Store 发起一个 action。 这个 effect 是非阻塞型的,并且所有向下游抛出的错误(例如在 reducer 中),都不会冒泡回到 saga 当中。

all

创建一个 Effect 描述信息,用来命令 middleware 并行地运行多个 Effect,并等待它们全部完成。这是与标准的 Promise#all 相当对应的 API。

更多API请查看Saga文档

总结

saga的用法比较简单,分为4步。

  1. 创建saga并且将使用takeEvery给每一个符合patternaction都增加一个对应的saga处理函数。
  2. 使用all导出编写的saga。
  3. 创建saga中间件,在使用redux创建store时,应用saga中间件。
  4. 运行中间件。

感谢阅读。

react系列(六)Redux Saga的更多相关文章

  1. [React] 14 - Redux: Redux Saga

    Ref: Build Real App with React #14: Redux Saga Ref: 聊一聊 redux 异步流之 redux-saga  [入门] Ref: 从redux-thun ...

  2. react native redux saga增加日志功能

    redux-logger地址:https://github.com/evgenyrodionov/redux-logger 目前Reac native项目中已经使用redux功能,异步中间件使用red ...

  3. react系列(五)在React中使用Redux

    上一篇展示了Redux的基本使用,可以看到Redux非常简单易用,不限于React,也可以在Angular.Vue等框架中使用,只要需要Redux的设计思想的地方,就可以使用它. 这篇主要讲解在Rea ...

  4. react系列(四)Redux基本概念和使用

    Redux基本概念和使用 先从Flux开始 先放一个Flux官网的链接.需要fq. Flux是Facebook提出的一种构建客户端网页应用的应用架构,它是一种抽象程度很高的设计模式,鼓励单向数据流. ...

  5. react系列教程

    这个系列将从基础语法讲起,把react全家桶都讲到,然后到具体的使用,最后完成后,会写一个完整的demo. 前置要求: 基本的CSS,JS要熟练. 部分ES6语法需要了解.可以参考下面提到的阮一峰老师 ...

  6. 在React中使用Redux

    这是Webpack+React系列配置过程记录的第六篇.其他内容请参考: 第一篇:使用webpack.babel.react.antdesign配置单页面应用开发环境 第二篇:使用react-rout ...

  7. React 系列教程 1:实现 Animate.css 官网效果

    前言 这是 React 系列教程的第一篇,我们将用 React 实现 Animate.css 官网的效果.对于 Animate.css 官网效果是一个非常简单的例子,原代码使用 jQuery 编写,就 ...

  8. CSS 魔法系列:纯 CSS 绘制各种图形《系列六》

    我们的网页因为 CSS 而呈现千变万化的风格.这一看似简单的样式语言在使用中非常灵活,只要你发挥创意就能实现很多比人想象不到的效果.特别是随着 CSS3 的广泛使用,更多新奇的 CSS 作品涌现出来. ...

  9. WCF编程系列(六)以编程方式配置终结点

    WCF编程系列(六)以编程方式配置终结点   示例一中我们的宿主程序非常简单:只是简单的实例化了一个ServiceHost对象,然后调用open方法来启动服务.而关于终结点的配置我们都是通过配置文件来 ...

随机推荐

  1. ArcGIS中国工具(ArcGISCTools)2.0在线视频

    查看地址:http://i.youku.com/gisoracle 在线看的不太清楚,支持下载视频地址 使用手册下载地址:http://pan.baidu.com/s/1kTsTyXT操作视频下载地址 ...

  2. windows 下进程与线程的遍历

    原文:http://www.cnblogs.com/Apersia/p/6579376.html 在Windows下进程与线程的遍历有好几种方法. 进程与线程的遍历可以使用<TlHelp.h&g ...

  3. Ubuntu 18.04 的网络配置

    netplan简介 目前,ubuntu18.04上使用了netplan 作为网络配置工具:在终端上配置网络参数跟之前的版本有比较大的差别 Netplan工作流程如下图所示:通过读取  /etc/net ...

  4. restful知识点之一CBV

    urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^FBVTEST/', views.FBV_Test.as_view()), ] url ...

  5. Android学习——Service(二)

    今天来介绍Service的第二种使用方式,Bind方式 Bind方式启动服务 Bind方式和Start方式启动很类似,都是通过Intent来启动,不同的是,Bind方式需要传入三个参数,如下: Int ...

  6. SQL Server ->> Database Promgramming Object Security Control(数据库编程对象安全控制)

    对于SQL Server内编程对象的安全控制是今天我在思考的问题.在MSDN上找到了几篇有用的文章. 首先微软推荐了三种做法: 1)第一种做法是在SQL Server中对一个应用程序对应创建应用程序角 ...

  7. How I explained OOD to my wife

    Introduction My wife Farhana wants to resume her career as a software developer (she started her car ...

  8. 【NLP_Stanford课堂】文本分类1

    文本分类实例:分辨垃圾邮件.文章作者识别.作者性别识别.电影评论情感识别(积极或消极).文章主题识别及任何可分类的任务. 一.文本分类问题定义: 输入: 一个文本d 一个固定的类别集合C={c1,c2 ...

  9. 【Leetcode】【Medium】Gas Station

    There are N gas stations along a circular route, where the amount of gas at station i is gas[i]. You ...

  10. 使用CoreImage教程

    使用CoreImage教程 CoreImage包含有很多实用的滤镜,专业处理图片的库,为了能看到各种渲染效果,请使用如下图片素材. 现在可以开始教程了: #define FIX_IMAGE(image ...