redux-saga框架使用详解

什么是redux-saga

redux-saga 是一个用于管理 Redux 应用异步操作的中间件(又称异步 action)。redux-saga 通过创建 Sagas 将所有的异步
操作逻辑收集在一个地方集中处理,可以用来代替 redux-thunk 中间件。

一、Saga 辅助函数

redux-saga提供了一些辅助函数,用来在一些特定的action 被发起到Store时 派生任务,下面我先来讲解两个辅助函数:
takeEvery 和 takeLatest

takeEvery

例如:每次点击 Fetch 按钮时,我们发起一个 FETCH_REQUESTED 的 action。 我们想通过启动一个任务从服务器
获取一些数据,来处理这个action
首先我们创建一个将执行异步 action 的任务:

	import { call, put } from 'redux-saga/effects'
	
	export function* fetchData(action) {
	   try {
	      const data = yield call(Api.fetchUser, action.payload.url);
	      yield put({type: "FETCH_SUCCEEDED", data});
	   } catch (error) {
	      yield put({type: "FETCH_FAILED", error});
	   }
	}

然后在每次 FETCH_REQUESTED action 被发起时启动上面的任务

	import { takeEvery } from 'redux-saga'

	function* watchFetchData() {
	
	  yield* takeEvery("FETCH_REQUESTED", fetchData)
	}

注意:上面的 takeEvery 函数可以使用下面的写法替换

takeLatest

在上面的例子中,takeEvery 允许多个 fetchData 实例同时启动,在某个特定时刻,我们可以启动一个新的 fetchData
任务, 尽管之前还有一个或多个 fetchData 尚未结束

如果我们只想得到最新那个请求的响应(例如,始终显示最新版本的数据),我们可以使用 takeLatest 辅助函数

	import { takeLatest } from 'redux-saga'

	function* watchFetchData() {
	  yield* takeLatest('FETCH_REQUESTED', fetchData)
	}

和takeEvery不同,在任何时刻 takeLatest 只允许执行一个 fetchData任务,并且这个任务是最后被启动的那个,如果之
前已经有一个任务在执行,那之前的这个任务会自动被取消

二、Effect Creators

redux-saga框架提供了很多创建effect的函数,下面我们就来简单的介绍下开发中最常用的几种

  • take(pattern)
  • put(action)
  • call(fn, …args)
  • fork(fn, …args)
  • select(selector, …args)
take(pattern)

take函数可以理解为监听未来的action,它创建了一个命令对象,告诉middleware等待一个特定的action, Generator会暂停,直到一个与
pattern 匹配的action被发起,才会继续执行下面的语句,也就是说,take是一个阻塞的 effect

用法:

function* watchFetchData() {
   while(true) {
     // 监听一个type为 'FETCH_REQUESTED' 的action的执行,直到等到这个Action被触发,才会接着执行下面的 yield fork(fetchData)  语句
     yield take('FETCH_REQUESTED');
     yield fork(fetchData);
   }
}
put(action)

put函数是用来发送action的 effect,你可以简单的把它理解成为redux框架中的dispatch 函数,当put一个action后,reducer中就会计算新
的state并返回,注意: put 也是阻塞 effect

用法:

export function* toggleItemFlow() {
    let list = []
    // 发送一个type为 'UPDATE_DATA' 的Action,用来更新数据,参数为 `data:list`
    yield put({
      type: actionTypes.UPDATE_DATA,
      data: list
    })
}

call(fn, …args)

call函数你可以把它简单的理解为就是可以调用其他函数的函数,它命令 middleware 来调用fn 函数, args为函数的参数,注意: fn 函数
可以是一个 Generator 函数,也可以是一个返回 Promise 的普通函数,call 函 数也是阻塞 effect

用法:

export const delay = ms => new Promise(resolve => setTimeout(resolve, ms))

export function* removeItem() {
  try {
    // 这里call 函数就调用了 delay 函数,delay 函数为一个返回promise 的函数
    return yield call(delay, 500)
  } catch (err) {
    yield put({type: actionTypes.ERROR})
  }
}
fork(fn, …args)

fork 函数和 call 函数很像,都是用来调用其他函数的,但是fork函数是非阻塞函数,也就是说,程序执行完 yield fork(fn, args) 这一行代码
后,会立即接着执行下一行代码语句,而不会等待fn函数返回结果后,在执行下面的语句

用法:

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

export default function* rootSaga() {
  // 下面的四个 Generator 函数会一次执行,不会阻塞执行
  yield fork(addItemFlow)
  yield fork(removeItemFlow)
  yield fork(toggleItemFlow)
  yield fork(modifyItem)
}

select(selector, …args)

select 函数是用来指示 middleware调用提供的选择器获取Store上的state数据,你也可以简单的把它理解为redux框架中获取store上的 state数据一样的功能 :store.getState()

用法:

export function* toggleItemFlow() {
     // 通过 select effect 来获取 全局 state上的 `getTodoList` 中的 list
     let tempList = yield select(state => state.getTodoList.list)
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值