当前位置: 移动技术网 > IT编程>开发语言>JavaScript > react系列(六)Redux Saga

react系列(六)Redux Saga

2018年11月05日  | 移动技术网IT编程  | 我要评论

在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的防抖版本。
具体例子可以查看。

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. 运行中间件。

感谢阅读。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网