redux-saga入门


资料

文档:

参考文章:

redux-saga简介

使用 dispatch 往 store 发送 action 的这个过程是可以被拦截的, 自然而然地就可以在这里增加各种中间件Middleware。redux-saga是redux的中间件,主要负责从action派发到更新store中间具有副作用行为的处理。
在这里插入图片描述

sagas.js文件

import {
    all, put, takeEvery } from 'redux-saga/effects'

function* increment() {
   
    // 相当于:dispatch({ type: 'increment' })
    yield put({
    type: 'increment' }) 
}

function* watchIncrement() {
   
    // 监听类型为increment_saga的action,监听到启动increment
    yield takeEvery('increment_saga', increment) 
}

function* rootSaga() {
   
    // 启动watchIncrement
    yield all([watchIncrement()])
}

export default rootSaga

这些generator函数我们叫它saga。saga中yield 后面的内容我们称呼它为Effect(redux-saga的任务单元),在Effects中我们可以进行启动其它saga,也可以处理一些副作用操作。Effects是一些简单对象,如下put({ type: ‘increment’ }),我们使用redux-saga提供的put方法创建一个Effect对象。如果直接打印Effect:

console.log(put({
    type: 'increment' }));

在这里插入图片描述

在 redux-saga 的世界里,Saga 都用 Generator 函数实现。我们从 Generator 里 yield 纯 JavaScript 对象以表达 Saga 逻辑。 我们称呼那些对象为 Effect。Effect 是一个简单的对象,这个对象包含了一些给 middleware 解释执行的信息。 你可以把 Effect 看作是发送给 middleware 的指令以执行某些操作(调用某些异步函数,发起一个 action 到 store,等等)。

常用API

takeLatest

takeLatest是非阻塞的。

顾名思义takeEvery监听每一次对应action的派发,而takeLatest监听最后一次action的派发,并自动取消之前已经在启动且任在执行的任务。 这个和我们的防抖很类似。

takeLatest(pattern, saga, …args): 监听类型为pattern的action的派发,当监听到该类型的action,将执行第二个参数saga,且如果存在上一次已经启动且仍在运行的该saga,takeLatest将取消上一次该saga的运行。

  • pattern:takeLatest将监听类型为pattern的action的派发。takeLatest第一个参数是*,即不再匹配某一个具体的action,而是匹配所有的action
  • saga:监听到对应action,启动对应saga。
  • args:传递给saga函数的参数。如果takeLatest没有传入args,那么saga函数的参数只有一个,即类型为pattern的action。如果takeLatest传入了其它args参数,那么saga函数的参数将像这样(args,action)。

takeLatest会创建一个一直执行的任务,该任务的功能是监听类型为xxx的action执行对应的saga。且takeLatest是非阻塞的,即中间件接收到takeLatest创建的Effect之后就去创建一个一直执行的任务,同时继续执行yield takeLatest(‘xxx’, login)后面的代码。takeEvery同理。

function* increment() {
   
    yield put({
    type: 'increment' }) 
}

function* watchIncrement() {
   
    yield takeLatest('increment_saga', increment) 
}

takeEvery

takeEvery是非阻塞的。

takeEvery(pattern, saga, ...args): 监听类型为pattern的action的派发,当监听到该类型的action,将执行第二个参数saga,且args将作为参数传递给saga函数,与takeLatest唯一不同即 不会取消之前监听到类型pattern的action且正在执行的saga任务。

function* increment() {
   
    yield put({
    type: 'increment' }) 
}

function* watchIncrement() {
   
    // 监听类型为increment_saga的action,监听到启动increment
    yield takeEvery('increment_saga', increment) 
}

take

take是阻塞的。

take接受的参数type即用来匹配action的类型,take作用是创建一个Effect,命令中间件等待指定的action到来(下方代码是等待类型为loginOut的action到来),只监听一次。在该action到来之前,将暂停当前Generator。take()的返回值是当前aciton。

function* loginOut() {
   
    yield put({
    type: 'loginSuccess', loginInfo: {
    success: false, name: '', password: '' } })
}
// 监听登录登出saga
function* watchLogin() {
   
    yield takeLatest('login', login)
  
    // 1,使用take等待类型loginOut的action的到来,take将阻塞当前Generator
    const action = yield take('loginOut')
    // 2,take监听到类型loginOut的action,执行yield call(loginOut),即继续登出操作
    yield call(loginOut)
}

当yield take(‘loginOut’)等待的类型为loginOut的action到来时,Generator开始继续执行后面的代码,即 yield call(loginOut),call将创建一个Effect,命令中间件执行loginOut方法,完成后续的登出操作,因为call方法是阻塞的,所以当前Generator会等待loginOut的完成。当loginOut完成之后,该Generator函数将执行完毕。

Generator函数(即watchLogin)将执行完毕退出后,此时只有yield takeLatest(‘login’, login)创建的监听login的任务仍然在后台运行。所以往后再有退出的loginOut类型的action派发过来的,并没有任何任务对其保持监听,所以将中间件将忽略掉后续过来的loginOut类型的action。

delay

delay(timeout,[val]): 产生一个阻塞的Effect(Effect=>任务单元),阻塞timeout毫秒,并返回val(val非必传)。大白话就是yield delay(1000,‘Love U’)将阻塞当前代码执行1000ms,并且返回’Love U’。

import {
    put, delay } from 'redux-saga/effects'

function* increment() {
   
    yield put({
    type: 
  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值